首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用反射覆盖2+2=5

使用反射覆盖2+2=5
EN

Stack Overflow用户
提问于 2020-09-04 21:32:42
回答 2查看 283关注 0票数 2

请原谅我,我知道这是个奇怪的问题。

我刚刚偶然发现了Java的反射库,特别是这段来自莱克斯·弗里德曼的视频的代码,它覆盖了2 + 2 = 5

代码语言:javascript
复制
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返回一个空数组:

代码语言:javascript
复制
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)

当我尝试使用时,classgetClass都不是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目标?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-04 22:01:24

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

Int.getClass是在类Int的同伴对象上调用的getClass,这是错误的。

将代码转换为Scala是

代码语言:javascript
复制
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

票数 5
EN

Stack Overflow用户

发布于 2020-09-04 21:58:46

如果在IntegerCache类中检查Integer内部类。执行工作的某些部分如下:

代码语言:javascript
复制
        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。

代码语言:javascript
复制
0 -> 128
1 -> 129
2 -> 130
3 -> 131
4 -> 132
5 -> 133

array132 = array133;表达式使缓存中的4=5。因此,每当应用程序从缓存中调用索引4时,Integer 5就会被返回。

在Scala方面,我没有Scala方面的经验,但它不是使用JVM将自己编译成字节代码吗?因此,也许Scala不使用JDK,而且它的Int实现是不同的,这就是您得到错误的原因(似乎可以根据@Dmytro Mitin的答案使用JDK的Integer )。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63748255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档