使用反射覆盖 2 + 2 = 5

Jam*_*ley 2 java reflection scala scala-java-interop

容忍我,我明白这是一个奇怪的问题。

我刚刚偶然发现了 Java 的反射库,特别是 Lex Fridman 视频中的这段代码,它覆盖了2 + 2 = 5

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] array = (Integer[]) c.get(cache);
        array[132] = array[133];

        System.out.printf("%d",2 + 2);
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图通过将其转换为等效的 Scala 形式来了解它正在做什么,但它没有编译为Int.getClass.getDeclaredClasses返回一个空数组:

import java.lang.reflect.Field

val cache: Class[_] = Int.getClass.getDeclaredClasses.head
// above line throws java.util.NoSuchElementException: next on empty iterator

val c: Field = cache.getDeclaredField("cache")
c.setAccessible(true)
val array = c.get(cache).asInstanceOf[Array[Int]]
array(132) = 5

println(2+2)
Run Code Online (Sandbox Code Playgroud)

当我尝试使用它时,方法既没有class也没有,所以我尝试使用;我的印象是 Scala只是 Java 的一个包装器- 不是这样吗?getClassIntegerIntIntInteger

我也试过:

  • new Integer() (抱怨“带有替代方法的重载方法构造函数Integer”)
  • new Int() (“类 Int 是抽象的;不能被实例化”)
  • 使用class T extends Int ... new T.getClass....(来自最终类的非法继承)扩展 Int 和 Integer

为什么这在不能用 Scala 编译的 Java 中有效?我怎样才能实现我2 + 2 = 5在 Scala 中的愚蠢目标?

Dmy*_*tin 5

java.lang.Integer应该代替scala.Int.

Int.getClassgetClass调用的类的同伴对象Int,这是不对的。

将代码翻译成 Scala 是

val cache = classOf[Integer].getDeclaredClasses.apply(0)
val c = cache.getDeclaredField("cache")
c.setAccessible(true)
val array = c.get(cache).asInstanceOf[Array[Integer]]
array(132) = array(133)
println(2 + 2) // 5
Run Code Online (Sandbox Code Playgroud)

我的印象是 ScalaInt只是 Java 的一个包装器Integer- 不是这样吗?

它不是。通常scala.Int对应于 Java int

https://github.com/scala/scala/blob/2.13.x/src/library/scala/Int.scala