我有一个 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参数构造函数
这可能吗?
答案 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传递适当的位置参数,可以调用构造函数和方法。
这里的范围如下:
示例:
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)
}
}