Создайте экземпляр класса Scala из Java и используйте параметры по умолчанию для конструктора - программирование
Подтвердить что ты не робот

Создайте экземпляр класса Scala из Java и используйте параметры по умолчанию для конструктора

У меня есть класс 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()
}

Java

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

Однако я хотел бы избавиться от трюка с перегрузкой конструктора и использовать конструктор 0 param

Возможно ли это?

4b9b3361

Ответ 1

Кажется, такого пути нет: https://issues.scala-lang.org/browse/SI-4278

Проблема: конструктор по умолчанию no-args должен быть сгенерирован для классов со всеми необязательными аргументами...

Lukas Rytz: в отношении однородности языка мы решили не исправлять эту проблему - поскольку это проблема совместимости с фреймворками, мы считаем, что ее нельзя фиксировать на уровне языка.

обходные пути: повторить по умолчанию или абстрагироваться над одним или поместить по умолчанию int конструктор с нулевым аргументом

Затем Лукас предлагает такое же решение, что и вы:

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

В общем случае, если у вас есть класс Scala с аргументами по умолчанию и вы хотите создать экземпляр в Java, переопределяя 0, 1 или более значений по умолчанию, не указывая все, рассмотрите возможность расширения API Scala для включения 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)
  }
}