请原谅我,我知道这是个奇怪的问题。
我刚刚偶然发现了Java的反射库,特别是这段来自莱克斯·弗里德曼的视频的代码,它覆盖了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返回一个空数组:
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() (抱怨“重载的方法构造器包含其他选项”)new Int() (“类Int是抽象的;不能实例化”)class T extends Int ... new T.getClass.... (来自最终类的非法继承)扩展Int和Integer为什么在Java中不使用Scala进行编译呢?我如何在Scala中实现我愚蠢的2 + 2 = 5目标?
发布于 2020-09-04 22:01:24
java.lang.Integer应该代替scala.Int。
Int.getClass是在类Int的同伴对象上调用的getClass,这是错误的。
将代码转换为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我当时的印象是,Scala的
Int只是Integer的包装器--不是吗?
事实并非如此。通常情况下,scala.Int对应于int。
https://github.com/scala/scala/blob/2.13.x/src/library/scala/Int.scala
发布于 2020-09-04 21:58:46
如果在IntegerCache类中检查Integer内部类。执行工作的某些部分如下:
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类的"cache“字段,即-128到127之间的值。但是在数组中,它们保持在一起,所以值0实际上是128 (因为首先有-128个值)+0。
0 -> 128
1 -> 129
2 -> 130
3 -> 131
4 -> 132
5 -> 133array132 = array133;表达式使缓存中的4=5。因此,每当应用程序从缓存中调用索引4时,Integer 5就会被返回。
在Scala方面,我没有Scala方面的经验,但它不是使用JVM将自己编译成字节代码吗?因此,也许Scala不使用JDK,而且它的Int实现是不同的,这就是您得到错误的原因(似乎可以根据@Dmytro Mitin的答案使用JDK的Integer )。
https://stackoverflow.com/questions/63748255
复制相似问题