Constructor.newInstance替换Scala对象

jqn*_*qno 6 reflection scala

我正在用Jackson调试反序列化问题,其中object似乎替换了Scala 实例。我设法将问题深入到以下代码:

object WaitWhat extends App {

  object XX

  val x1 = XX

  // Notice: no assignment!
  XX.getClass.getConstructor().newInstance()

  val x2 = XX

  println(x1)
  println(x2)
}
Run Code Online (Sandbox Code Playgroud)

输出为:

WaitWhat$XX$@5315b42e
WaitWhat$XX$@2ef9b8bc
Run Code Online (Sandbox Code Playgroud)

(当然,实际的哈希码每次运行都会更改。)

IntelliJ的调试器还指示x1x2确实是不同的实例,尽管的结果newInstance被完全忽略了。

我本来希望没有行动,或者某种例外。实际的对象实例怎么可能被此调用替换

Krz*_*sik 6

Scala中的对象具有私有构造函数,不能使用new调用它(因为它是私有的),但仍可以使用反射来调用。

在内部,该对象可以通过静态MODULE$字段访问。该字段是通过调用私有构造函数在内部创建的单例实例。

只要您使用Scala或Java代码访问对象,MODULE$就可以了。但是,您不能确定某些库是否不会使用反射使用私有构造函数来创建对象的其他实例。在这种情况下,每当调用私有构造函数时,都会创建该对象的新实例并将其重新分配给MODULE$

尤其是在使用不知道Scala对象存在的Java库的情况下,可能会发生这种情况。

请查看本文以获取更多详细信息。

无论如何,我只会为Jackson创建自定义解串器(类似于本文中描述的解决方案)。