Вопрос

Is there a way to dynamically instantiate a Scala case class having one or more default parameters specified?

I'm looking for the dynamic (reflection-based) equivalent of this:

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

Right now if I try this I get an exception:

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

If I add a value for age in my parameter array, no problem.

Это было полезно?

Решение 2

Argument with default value are a compile-time thing. The compiler will feed in the default value for a call where the parameter is missing. No such thing with reflection, all the less with java reflection, which is not aware at all of default arguments.

Другие советы

You can get default parameters as methods of object in runtime.

In case of constructor parameters - companion object methods (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

You can't rely on the name of this method. (scala 2.10.1):

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

I don't know how to get default parameters for constructor, but in case of case class you could get apply method default parameters. See this answer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top