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.
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.