使用反射覆盖 2 + 2 = 5
Using reflection to override 2 + 2 = 5
请耐心等待,我知道这是一个奇怪的问题。
我刚刚偶然发现了 Java 的反射库,特别是来自 a video by 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);
}
}
我试图通过将其翻译成等效的 Scala 形式来了解它在做什么,但它没有编译为 Int.getClass.getDeclaredClasses
returns 一个空数组:
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)
class
和 getClass
都不是 Integer
下的方法,当我尝试使用它时,所以我尝试使用 Int
;我的印象是 Scala 的 Int
只是 Java 的 Integer
的包装 - 不是这样吗?
我也试过:
new Integer()
(抱怨“重载方法构造函数 Integer with alternatives”)
new Int()
("class Int 是抽象的;无法实例化")
- 用
class T extends Int ... new T.getClass....
扩展 Int 和 Integer(从 final class 非法继承)
为什么它在不使用 Scala 编译的 Java 中有效?我怎样才能在 Scala 中实现 2 + 2 = 5
的愚蠢目标?
如果勾选IntegerCache
inner class inside Integer
class。部分实现如下:
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
默认情况下 -128(低)和 127(高)之间的整数(可能被选中是因为这些是典型应用程序中最常用的整数)。缓存大小为 256(因此 - 和 + 值将保持在一起)
在你的应用程序中,你得到 Integer class 的“缓存”字段,它是从 -128 到 127 的值。但是在数组中它们保持在一起,所以值 0 索引实际上是 128(因为有首先是 -128 个值) + 0.
0 -> 128
1 -> 129
2 -> 130
3 -> 131
4 -> 132
5 -> 133
你的数组[132] = 数组[133];表达式使缓存中有 4 = 5。所以每当应用程序从缓存中调用4的索引时,都会返回整数5。
对于 Scala 部分,我没有使用 Scala 的经验,但它使用 JVM 不只是为了将自身编译为字节码吗?所以也许 Scala 不使用 JDK 并且它的 Int 实现是不同的,这就是你得到错误的原因(似乎可以根据@Dmytro Mitin 的回答使用 JDK 中的整数)
java.lang.Integer
应该代替 scala.Int
.
Int.getClass
是 getClass
在 class 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
I was under the impression that Scala's Int
is just a wrapper around Java's Integer
- is this not the case?
不是。通常scala.Int
对应Javaint
.
https://github.com/scala/scala/blob/2.13.x/src/library/scala/Int.scala
请耐心等待,我知道这是一个奇怪的问题。
我刚刚偶然发现了 Java 的反射库,特别是来自 a video by 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);
}
}
我试图通过将其翻译成等效的 Scala 形式来了解它在做什么,但它没有编译为 Int.getClass.getDeclaredClasses
returns 一个空数组:
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)
class
和 getClass
都不是 Integer
下的方法,当我尝试使用它时,所以我尝试使用 Int
;我的印象是 Scala 的 Int
只是 Java 的 Integer
的包装 - 不是这样吗?
我也试过:
new Integer()
(抱怨“重载方法构造函数 Integer with alternatives”)new Int()
("class Int 是抽象的;无法实例化")- 用
class T extends Int ... new T.getClass....
扩展 Int 和 Integer(从 final class 非法继承)
为什么它在不使用 Scala 编译的 Java 中有效?我怎样才能在 Scala 中实现 2 + 2 = 5
的愚蠢目标?
如果勾选IntegerCache
inner class inside Integer
class。部分实现如下:
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
默认情况下 -128(低)和 127(高)之间的整数(可能被选中是因为这些是典型应用程序中最常用的整数)。缓存大小为 256(因此 - 和 + 值将保持在一起)
在你的应用程序中,你得到 Integer class 的“缓存”字段,它是从 -128 到 127 的值。但是在数组中它们保持在一起,所以值 0 索引实际上是 128(因为有首先是 -128 个值) + 0.
0 -> 128
1 -> 129
2 -> 130
3 -> 131
4 -> 132
5 -> 133
你的数组[132] = 数组[133];表达式使缓存中有 4 = 5。所以每当应用程序从缓存中调用4的索引时,都会返回整数5。
对于 Scala 部分,我没有使用 Scala 的经验,但它使用 JVM 不只是为了将自身编译为字节码吗?所以也许 Scala 不使用 JDK 并且它的 Int 实现是不同的,这就是你得到错误的原因(似乎可以根据@Dmytro Mitin 的回答使用 JDK 中的整数)
java.lang.Integer
应该代替 scala.Int
.
Int.getClass
是 getClass
在 class 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
I was under the impression that Scala's
Int
is just a wrapper around Java'sInteger
- is this not the case?
不是。通常scala.Int
对应Javaint
.
https://github.com/scala/scala/blob/2.13.x/src/library/scala/Int.scala