Библиотека Builder для Scala и Java

Мне нужна библиотека компоновщика, которую можно вызывать из Scala и Java. Достаточно просто в Scala, используя именованные параметры по умолчанию. Но как мне вызвать этот код из Java? Смотри ниже. Или, возможно, мне следует использовать свободный API, более общий для обоих языков?

Скала:

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 = ?

person eptx    schedule 13.06.2011    source источник


Ответы (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 может быть менее многословной для разработчика.

person montreal.eric    schedule 14.06.2011
comment
Обратите внимание, что я создал аналогичный, но отдельный вопрос о построителе безопасных типов. См. http://stackoverflow.com/questions/6347083/type-safe-buider-library-for-scala-and-java - person eptx; 14.06.2011