簡體   English   中英

從 Java 實例化一個 Scala 類,並使用構造函數的默認參數

[英]Instantiate a Scala class from Java, and use the default parameters of the constructor

我有一個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

這個技巧確實對我有用,但它很丑陋,我想知道是否有更好的方法:

斯卡拉

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 param 構造函數

那可能嗎?

看來,沒有這樣的方法: https : //issues.scala-lang.org/browse/SI-4278

問題:應該為具有全可選參數的類生成默認的無參數構造函數
...

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) }
}

有一個解決方案,請查看文章中的“默認參數”部分: 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: spline-core version: 0.3.1

更一般地說,如果您有一個帶有默認參數的 Scala 類,並且您想在 Java 中實例化覆蓋 0、1 或多個默認值而不必指定所有,請考慮擴展 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)
  }
}

public class App {
    public static void main(String[] args) {
        Foo f = new Foo.Builder()
            .withA("override a")
            .build();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM