5

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

1 に答える 1

3

http://www.scala-lang.org/node/2075の最後のステートメントで述べたように、デフォルトの引数はscalaとjavaの間で相互運用できません。

上記のコードをjavaから使用する方法を決定するには、おそらくjavapが役立ちます。あなたが投稿したものよりも小さな例を見てみましょう。例えば

case class PersonBob(a: String = "aa", b: String = null)

scalacを使用してこれをコンパイルし、生成されたクラスファイル(.class拡張子なし)でjavapを実行すると、次のようになります。

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バージョンはビルダーにとってそれほど冗長ではないと思います

于 2011-06-14T00:19:18.710 に答える