Динамическое создание Scala с аргументами по умолчанию

Есть ли способ динамически создать экземпляр класса Scala с одним или несколькими указанными параметрами по умолчанию?

Я ищу динамический (на основе отражения) эквивалент этого:

case class Foo( name:String, age:Int = 21 )
val z = Foo("John") 

Прямо сейчас, если я попробую это, я получаю исключение:

val const = Class.forName("Foo").getConstructors()(0)
val args = Array("John").asInstanceOf[Array[AnyRef]]
const.newInstance(args:_*)

Если я добавлю значение возраста в свой массив параметров, нет проблем.


person Greg    schedule 08.06.2013    source источник


Ответы (2)


Аргумент со значением по умолчанию - это вещь времени компиляции. Компилятор будет передавать значение по умолчанию для вызова, в котором параметр отсутствует. С рефлексией такого нет, тем более с java-рефлексией, которая вообще не знает аргументов по умолчанию.

person Didier Dupont    schedule 08.06.2013
comment
Вы можете получить значение по умолчанию во время выполнения как метод. - person senia; 09.06.2013
comment
Как? У меня (пока) нет экземпляра этого объекта - я нахожусь в процессе его создания. - person Greg; 09.06.2013
comment
@Greg в данном случае - объект-компаньон. - person senia; 09.06.2013

Вы можете получить параметры по умолчанию как методы объекта во время выполнения.

В случае параметров конструктора - методы объекта-компаньона (scala 2.9.3).

$ echo 'class Test(t: Int = 666)' > test.scala
$ scalac -Xprint:typer test.scala
...
<synthetic> def init$default$1: Int @scala.annotation.unchecked.uncheckedVariance = 666

Вы не можете полагаться на название этого метода. (скала 2.10.1):

scala> Test.$lessinit$greater$default$1
res0: Int = 666

Я не знаю, как получить параметры по умолчанию для конструктора, но на всякий случай из case class вы можете получить apply параметры метода по умолчанию. См. этот ответ.

person senia    schedule 09.06.2013
comment
@som-snytt: имя отличается в 2.9.3 и 2.10.1, поэтому не следует использовать имя, а генерировать с использованием defaultGetterName. - person senia; 09.06.2013
comment
@som-snytt: ваш комментарий заставляет меня хотеть создать метод `<init>`. - person senia; 09.06.2013