【问题标题】:Scala/java reflection - `newInstance` throws InstantiationExceptionScala/java 反射 - `newInstance` 抛出 InstantiationException
【发布时间】:2023-03-29 10:18:01
【问题描述】:
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 是一个实例化对象,而 config 包含 val config: Class[_ &lt;: Config] = classOf[Test]

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

【问题讨论】:

  • 只是一个问题。您尝试实例化的所有类是否都具有不带参数的构造函数?如果没有,可能就是这样。
  • 我无法重现您的错误
  • @Vlasec 好吧,不,我只是在实例化一个没有参数的简单配置类。有趣的是,它适用于我的主要代码。它在测试和工作表中失败。

标签: java scala reflection


【解决方案1】:

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

而内部类需要外部类的实例来构造。所以没有没有参数的构造函数,简单地调用newInstance()是行不通的。

【讨论】:

    【解决方案2】:

    我首先在 IntelliJ 想法中使用 ScalaWorkSheet 运行您的示例,并且我遇到了同样的错误,我的结论是反射在 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,有时可能会很糟糕,哈哈

    【讨论】:

      猜你喜欢
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多