从Java实例化Scala类,并使用构造函数的默认参数

时间:2012-10-24 23:41:36

标签: java scala

我有一个 Scala 类:

class Foo(val x:String = "default X", val y:String = "default Y" ) 

我想从 Java 中调用它,但使用默认参数

传递null不起作用(按预期分配null

new Foo(null,null); //both are instantiated as null

这个技巧对我有用,但它很难看,我想知道是否有更好的方法:

Scala的

class Foo(val x:String = "default X", val y:String = "default Y" ) {
  def this(x:Object) = this()
}

爪哇

new Foo(null); //no matter what I pass it should work

但是我想摆脱构造函数的重载技巧,并使用0参数构造函数

这可能吗?

3 个答案:

答案 0 :(得分:7)

似乎没有这样的方式:https://issues.scala-lang.org/browse/SI-4278

  

问题:应为具有全可选参数的类生成默认的no-args构造函数
  ...

     

Lukas Rytz :在语言一致性方面,我们决定不解决这个问题 - 因为这是与框架互操作的问题,我们认为不应该在语言层面修复它。

     

变通方法:重复一个默认值,或者对一个进行抽象,或者将一个默认值设置为零参数构造函数

然后Lukas提出了与你发现的相同的解决方案:

class C(a: A = aDefault, b: B = C.bDefault) {
  def this() { this(b = C.bDefault) }
}
object C { def bDefault = ... }

// OR

class C(a: A = aDefault, b: B) {
  def this() { this(b = bDefault) }
}

答案 1 :(得分:2)

有解决方案,请查看文章https://lampwww.epfl.ch/~michelou/scala/using-scala-from-java.html

中的“默认参数”部分

通过使用。$ default $ [number]格式从java传递适当的位置参数,可以调用构造函数和方法。

这里的范围如下:

  • 类构造函数:<< ClassName >>。init $ default $ 1表示在构造函数定义中设置的第一个参数默认值default $ 2表示第二个参数默认值,依此类推。
  • 方法调用:object.methodName $ default $ 1解析方法第一个参数在方法签名等中分配的默认值。

示例:

import za.co.absa.spline.core.SparkLineageInitializer;
SparkLineageInitializer.SparkSessionWrapper lineage = SparkLineageInitializer.SparkSessionWrapper(spark);
lineage.enableLineageTracking(lineage.enableLineageTracking$default$1());

在此示例中,maven依赖项为: groupId:za.co.absa.spline artifactId:样条核心 版本:0.3.1

答案 2 :(得分:1)

更一般地说,如果您有一个带有默认args的Scala类,并且您希望在Java中实例化覆盖0,1个或更多默认值而不必指定all,请考虑扩展Scala API以在随附对象中包含Builder。

case class Foo(
  a: String = "a",
  b: String = "b",
  c: String = "c")

object Foo {
  class Builder {
    var a: String = "a"
    var b: String = "b"
    var c: String = "c"
    def withA(x: String) = { a = x; this }
    def withB(x: String) = { b = x; this }
    def withC(x: String) = { c = x; this }
    def build = Foo(a, b, c)
  }
}