如何通过反射调用私有构造函数?

时间:2013-09-02 00:38:10

标签: scala reflection

当我从类成员中选择一个私有构造函数并尝试实例化一个对象时,会抛出java.lang.NoSuchMethod异常。

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> class test private( s: String ) {
     | def this( i: Int ) = this( i.toString ) // public
     | }
defined class test

scala> val mirror = runtimeMirror( getClass.getClassLoader )
mirror: reflect.runtime.universe.Mirror = JavaMirror with scala.tools.ns...

scala> val cls = mirror.classSymbol( classOf[test] )
cls: reflect.runtime.universe.ClassSymbol = class test

scala> cls.toType.members.toSeq
res0: reflect.runtime.universe.MemberScope = Scopes(constructor test, constructor test, value s, meth...

scala> val prv = res0( 1 ).asMethod
prv: reflect.runtime.universe.MethodSymbol = constructor test

scala> val pub = res0( 0 ).asMethod
pub: reflect.runtime.universe.MethodSymbol = constructor test

scala> mirror.reflectClass( cls ).reflectConstructor( pub ).apply( 1 )
res3: Any = test@6926e27

scala> mirror.reflectClass( cls ).reflectConstructor( prv ).apply( "1" )
java.lang.NoSuchMethodException: test.<init>(java.lang.String) ...

我希望找到一些方法,允许我将私有构造函数标记为可访问但我找不到。

2 个答案:

答案 0 :(得分:3)

这似乎是一个错误。

其他成员查找使用getDeclaredXXX,从this commit of ConstructorMirror之前和之后可以清楚地知道它始终是setAccessible

答案 1 :(得分:2)

使用this link作为灵感,我使用可能有用的Java反射做了一个例子:

class test private( s: String ) {
    def this( i: Int ) = this( i.toString ) // public
    override def toString() = "Value: " + s
}

val testClass = classOf[test]
val ctor = testClass.getDeclaredConstructor(classOf[String])
ctor.setAccessible(true)
val inst = ctor.newInstance("hello")
println(inst)

输出:

Value: hello