我正在用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
的结果被完全忽略了。
我本来希望没有行动,或者某种例外。
如何通过此调用将实际的对象实例替换为??答案 0 :(得分:5)
Scala中的对象具有私有构造函数,该构造函数不能用new调用(因为它是私有的),但仍可以使用反射来调用。
在内部,该对象由静态MODULE$
字段访问。此字段是通过调用私有构造函数在内部创建的单例实例。
只要您使用MODULE$
在Scala或Java代码中访问对象,就可以了。但是,您不能确定某些库是否不会使用反射使用私有构造函数来创建对象的其他实例。在这种情况下,每当调用私有构造函数时,都会创建该对象的新实例并将其重新分配给MODULE$
。
尤其是在使用不知道Scala对象存在的Java库的情况下,这种情况会发生。
请检查此article以获得更多详细信息。
无论如何,我只会为Jackson创建自定义解串器(类似于本文中描述的解决方案)。