我正在使用 Jackson 调试反序列化问题,其中 Scala object
实例似乎已被替换。我设法将问题深入到以下代码:
object WaitWhat extends App {
object XX
val x1 = XX
// Notice: no assignment!
XX.getClass.getConstructor().newInstance()
val x2 = XX
println(x1)
println(x2)
}
输出为:
WaitWhat$XX$@5315b42e
WaitWhat$XX$@2ef9b8bc
(当然,实际的哈希代码每次运行都会改变。)
IntelliJ 的调试器还表明 x1
和 x2
确实是不同的实例,尽管 newInstance
的结果被完全忽略。
我本以为会发生空操作,或者某种异常。实际的对象实例怎么可能被这个调用替换?
最佳答案
Scala 中的对象有一个私有(private)构造函数,不能用 new 调用(因为它是私有(private)的),但仍然可以使用反射调用。
在底层,该对象是通过静态MODULE$
字段访问的。该字段是通过调用私有(private)构造函数内部创建的单例实例。
只要使用 MODULE$
访问 Scala 或 Java 代码中的对象就可以了。但是,您不能确定某些库不会使用反射使用私有(private)构造函数创建对象的附加实例。在这种情况下,每当调用私有(private)构造函数时,都会创建该对象的一个新实例并将其重新分配给 MODULE$
。
如果您使用不知道 Scala 对象存在的 Java 库,这种情况尤其可能发生。
请检查此article了解更多详情。
无论如何,我只会为 Jackson 创建自定义解串器(类似于文章中描述的解决方案)。
关于scala - Constructor.newInstance 替换 Scala 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55702041/