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反射没有充分的了解。不知道为什么会这样。
答案 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()
无法工作。