问题
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/17003562/scala-dynamic-instantiation-with-default-arguments