- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
2.8.0.h: constructor, default parameter value and reflection
I'd like to create an instance using reflection. The
class has a single constructor which takes a parameter
which has a default value. How do I get to the correct
constructor in Scala?
Below is a test class which has one class with with two
constructors - and this one reflection works on. And
a second class which has a single constructor which
has a default value - and this one I can figure out how
to get a handle on so I can create an instance.
File Test.scala
import java.lang.reflect.Constructor
object Util {
val EMPTY_CLASS_ARRAY = Array[Class[_]]()
val EMPTY_OBJECT_ARRAY = Array[Any]()
}
class Builder[T](interfaceClass: Class[T]) {
def lookupClass(name: String) : Class[_ <: T] = {
var clz = Class.forName(name)
clz.asSubclass(interfaceClass)
}
def getConstructor(clz: Class[_ <: T],
parameterTypes: Array[Class[_]]): Constructor[_ <:
T] = {
clz.getConstructor(parameterTypes: _*)
}
def newInstance(constructor: Constructor[_ <: T],
parameterValues: Array[Any]): T = {
constructor.newInstance(parameterValues.map(_.asInstanceOf[AnyRef])
: _*)
}
}
class Works(name: String) {
def this() = this("Works")
def getName: String = name
}
class DoesNotWork(name: String = "DoesNotWork") {
def getName: String = name
}
import Util._
object Main {
def doWorks {
val builder = new Builder[Works](classOf[Works])
var clz: Class[_ <: Works] = builder.lookupClass("Works")
var constructor = builder.getConstructor(clz, EMPTY_CLASS_ARRAY)
var works: Works = builder.newInstance(constructor, EMPTY_OBJECT_ARRAY)
println("name="+works.getName)
}
def doesNotWork {
val builder = new Builder[DoesNotWork](classOf[DoesNotWork])
var clz: Class[_ <: DoesNotWork] = builder.lookupClass("DoesNotWork")
var constructor = builder.getConstructor(clz, EMPTY_CLASS_ARRAY)
var notworks: DoesNotWork = builder.newInstance(constructor,
EMPTY_OBJECT_ARRAY)
println("name="+notworks.getName)
}
def usage {
println("Enter either: \"works\" or \"doesnotworks\"")
}
def main(args: Array[String]) {
args match {
case Array("works") => doWorks
case Array("doesnotwork") => doesNotWork
case _ => usage
}
}
}
> scalac Test.scala
> scala Main
Enter either: "works" or "doesnotwork"
> scala Main works
name=Works
> scala Main doesnotwork
java.lang.NoSuchMethodException: DoesNotWork.()
at java.lang.Class.getConstructor0(Class.java:2706)
at java.lang.Class.getConstructor(Class.java:1657)
at Builder.getConstructor(Works.scala:19)
at Main$.doesNotWork(Works.scala:51)
at Main$.main(Works.scala:61)
at Main.main(Works.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:55)
at
scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:22)
at
scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:61)
at
scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:55)
at
scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:61)
at
scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:153)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Using reflection how can I tell if a class has constructors that
have default parameters and how can I call the one that will
build an instance using the default value.
Thanks
Richard










Re: 2.8.0.h: constructor, default parameter value and reflecti
this class has no parameterless constructor in bytecode. if you want
to use the default argument you have to call the method
DoesNotWork$.MODULE$.init$default$1
to get the value "DoesNotWork" back, and then feed this into the
1-argument constructor.
more documentation on how defaults work is here: http://www.scala-lang.org/sid/1
lukas
On Tue, Mar 30, 2010 at 03:53, richard emberson <richard [dot] emberson [at] gmail [dot] com> wrote: