質問

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