java - Scala 和 Java 的构建器库

标签 java scala scala-java-interop

我需要一个可以从 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 = ?

最佳答案

默认参数在 scala 和 java 之间不可互操作,正如 http://www.scala-lang.org/node/2075 的最后声明中提到的那样.

要确定如何从 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 版本对于构建者来说可能不那么冗长

关于java - Scala 和 Java 的构建器库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6337444/

相关文章:

java - 如何将对象数组中的元素转换为字符串数组?

java - 横向视频 View

java - 对 API 调用进行分组,以便 UI 可以干净地调用它们并获得响应 - 设计

scala - 如何过滤对象数据?

java - 关闭特定 java 线程的 outputLOG 中的日志记录语句

xml - Scala:处理可选的 XML 元素和 Case 类

scala - 执行Shell进程时设置当前工作目录

scala - 使用案例类No Manifest的Scala Dynamic Parse Json可用于T

实现 Java 接口(interface)的 Scala 类 - 具有相同删除的双重定义

java - Scala "object"变量在 Java 中不可见吗?