scala - Constructor.newInstance 替换 Scala 对象

标签 scala reflection

我正在使用 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 的调试器还表明 x1x2 确实是不同的实例,尽管 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/

相关文章:

java - 如何检查代码库中是否有任何方法调用

scala - 具有子命令支持的Scala命令行解析器

Scala 案例类忽略 Spark shell 中的导入

c# - 无法在 MVC 应用程序中加载文件或程序集 'System.Reflection.TypeExtensions 错误

c# - 如何获取字段类型名称?

entity-framework - 识别和筛选实体数据对象中的导航属性

scala - 为什么ClassTag的runtimeClass方法返回一个通配符类?

scala - 如何将一个向量插入矩阵?

exception - Scala 中的@throws 问题

java - 将 java 函数 URLDecoder.decode 应用于 Spark 3 中的整个列