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

2022-09-03 02:36:44

我有一个Scala类:

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

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

传递不起作用(它分配 ,如预期的那样)nullnull

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

这个技巧确实对我有用,但它很丑陋,我想知道是否有更好的方法:

斯卡拉

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参数构造函数

这可能吗?


答案 1

似乎没有这样的方式: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) }
}

答案 2

有一个解决方案,请查看文章中的“默认参数”部分:https://lampwww.epfl.ch/~michelou/scala/using-scala-from-java.html

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

此处的范围如下:

  • 类构造函数:<<类名 >>.init$default $1 表示第一个参数的值 默认值 在构造函数定义中设置的默认值 默认值为 $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:spline-core 版本:0.3.1


推荐