Библиотека Builder для Scala и Java
Мне нужна библиотека для сборки, которую можно вызывать из Scala и Java. Достаточно просто в Scala с использованием именованных параметров по умолчанию. Но как мне вызвать этот код из Java? Увидеть ниже. Или, может быть, мне стоит использовать свободный API, более распространенный для обоих языков?
Scala:
case class Person(gender:Gender.Value, firstName:String, lastName:String){
def fullName = lastName+", "+firstName
override def toString = firstName+","+lastName+","+gender
}
case class PersonBob(
gender:Gender = GenderBob().build,
firstName:String = null,
lastName:String = null) {
def build = Person(
gender,
if(firstName == null) NameBob(if(gender==Gender.Male) engMaleNames
else engFemaleNames).build else firstName,
if(lastName==null) NameBob(engLastNames).build
else lastName
)
}
Использование:
val p1 = PersonBob().build
val p2 = PersonBob(lastName = "Jones").build
Использование Java:
Person p1 = ?
Person p2 = ?
1 ответ
Аргументы по умолчанию не совместимы между Scala и Java, как упоминалось в самом последнем утверждении http://www.scala-lang.org/node/2075.
Чтобы определить, как использовать код выше из java, возможно, javap может помочь. давайте возьмем меньший пример, чем вы опубликовали. например
case class PersonBob(a: String = "aa", b: String = null)
компилируя это с помощью scalac, а затем запустив javap для созданного файла класса (без расширения.class), мы получим
public class PersonBob extends java.lang.Object implements scala.ScalaObject,scala.Product,scala.Serializable {
public static final java.lang.String apply$default$2();
public static final java.lang.String apply$default$1();
public static final java.lang.String init$default$2();
public static final java.lang.String init$default$1();
public static final scala.Function1 tupled();
public static final scala.Function1 curry();
public static final scala.Function1 curried();
public scala.collection.Iterator productIterator();
public scala.collection.Iterator productElements();
public java.lang.String a();
public java.lang.String b();
public PersonBob copy(java.lang.String, java.lang.String);
public java.lang.String copy$default$2();
public java.lang.String copy$default$1();
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public boolean canEqual(java.lang.Object);
public PersonBob(java.lang.String, java.lang.String);
}
мы можем видеть, что единственный конструктор у нас есть
public PersonBob(java.lang.String, java.lang.String);
так что в вашем случае ваш код Java будет выглядеть примерно так
Person p1 = new PersonBob(new GenderBob().build(), null, null)
Person p2 = new PersonBob(new GenderBob().build(), null, "Jones")
предполагая, что класс GenderBob не принимает параметров в своем конструкторе. Что касается того, насколько свободно это происходит в Java, я полагаю, что в конечном итоге это дело вкуса, но, по моему скромному мнению, версия Java может быть менее многословной для разработчика