2011-06-13 38 views
5

我需要一個可以從Scala和Java調用的構建器庫。在Scala中使用默認的命名參數足夠簡單。但是,我如何從Java調用此代碼?見下文。或者,我應該使用兩種語言更通用的流暢API?適用於Scala和Java的Builder庫

斯卡拉:

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

回答

3

默認參數不是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版本可能不是一個生成器的詳細信息

+0

請注意,我已經創建了一個類似但單獨的問題關於類型安全的建造者。參見[http://stackoverflow.com/questions/6347083/type-safe-buider-library-for-scala-and-java](http://stackoverflow.com/questions/6347083/type-safe-buider-library - 用於-階和Java)可 – eptx 2011-06-14 16:50:20