Scala / java反射 - `newInstance`抛出InstantiationException

时间:2017-11-09 12:49:34

标签: java scala reflection

object classof extends App {

 trait Config {
    def test(): Unit
  }

  case class Test() extends Config {
    override def test(): Unit = println("test")
  }

  val s = classOf[Test]

  s.newInstance().test()

}

上面的代码运行正常,但是当您将其作为scala工作表运行时,它会抛出InstantiationException

Caused by: java.lang.NoSuchMethodException: 
reflection.A$A20$A$A20$Test.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)

我主要在执行测试时遇到此问题。例如

Animal.config.newInstance().test其中Animal是实例化对象,配置包含val config: Class[_ <: Config] = classOf[Test]

我对java反射没有充分的了解。不知道为什么会这样。

2 个答案:

答案 0 :(得分:1)

我首先使用ScalaWorkSheet在IntelliJ构思中运行您的示例,我感觉到同样的错误,我的结论是scala表中的反射没有很好地实现,对我来说日志是:

(我尝试了不同的方式,期待不同的结果):

trait Config {
  def test(): Unit
}

case class Test() extends Config {
  override def test(): Unit = println("test")
}

Test.getClass.getSimpleName

val t: Test = classOf[Test].getConstructors()(0).newInstance().asInstanceOf[Test]

t.test()

java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(TestingSO.sc)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(TestingSO.sc:58)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(TestingSO.sc:41)
    at java.lang.reflect.Constructor.newInstance(TestingSO.sc:419)
...

最罕见的是:

sun.reflect.NativeConstructorAccessorImpl.newInstance0(TestingSO.sc)

这是我的scala的名字

然后我做了一个简单的scala类:

class Testing {
}

trait Config {
  def test(): Unit
}

case class Test() extends Config {
  override def test(): Unit = println("test")
}

object Main{
  def main(args: Array[String]): Unit = {
    val s = classOf[Test]

    s.newInstance().test()
  }
}

工作得很好......

<强>结论

小心Scala Sheet,有时候可能会感到害羞哈哈

答案 1 :(得分:0)

请注意A$A20$A$A20$Test名称。它暗示这实际上是一个内部类(工作表必须将代码包装到类/对象中,因为Scala不直接支持顶级代码;您将在REPL中看到相同的内容)。

内部类需要构造外部类的实例。因此,没有没有参数的构造函数,只是调用newInstance()无法工作。