Java如何重新定义基本的int值

时间:2018-08-30 13:39:12

标签: java

所以我知道有可能以某种方式重新定义Java中的基本int,例如使1 = 2,这样,如果执行int x = 1 + 2,则x等于4。

有人知道这样做的语法吗?

1 个答案:

答案 0 :(得分:4)

很好玩,我决定去拍照。

您大概听说的是,您可能会破坏Integer的缓存以实现此目的。

在进一步介绍之前,这里是代码:

package test;

import java.lang.reflect.Field;

public class BreakMath {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
            IllegalArgumentException, IllegalAccessException {

        Class<?> integerCache = Class.forName("java.lang.Integer$IntegerCache");
        Field field = integerCache.getDeclaredField("cache");
        field.setAccessible(true);
        Integer[] cache = (Integer[]) field.get(null);
        cache[1 + 128] = 2;
        System.out.println(1 + 1);
        System.out.println(1 + Integer.valueOf(1));
        System.out.println(Integer.valueOf(1) + Integer.valueOf(1));
    }
}

这将输出以下内容:

2
3
4

到底发生了什么?

您没有在Java中更改1值。实际上,您正在利用Integer.class拥有的内部缓存(在Oracle的JVM和openJDK中,在其他供应商的JVM中可能有所不同)

通过反射,我们到达Integer缓存,然后更改该值。从那时起,Integer.valueOf()使用该缓存,您可以实现此目的……但是,如果您注意到在使用普通原语进行数学运算时,它将不起作用。 如果您已经完成了新的Integer(1)的操作(因为不使用缓存),它将无法正常工作。

但是在任何可以进行JVM自动装箱的地方,您都可以进入。例如,如果您有方法

public static void printInteger(Integer i) {
        System.out.println(i);
 }

并用

调用
printInteger(1)

将自动装箱,将使用缓存,并且您将获得2张打印纸。

注意 默认情况下,它的作用范围是-128至128。这是默认的缓存,但是正如您在code中所看到的,您可以更改缓存大小使用-XX:AutoBoxCacheMax。