Integer缓存之如何让java算数运算1+1=3?

  |   1,999 浏览

    这次我们来玩点大的,当我们运行如下代码时,我们都会斩钉截铁的咆哮道这输出结果肯定是:2
    没错,下面这段代码运行结果必须是2,三岁小孩都知道1+1=2。

    public class Calc {
    
    	public static void main(String[] args) throws Exception{
    		
    		//todo
    		
    		Integer i = 1;
    		Integer j = 1;
    		Integer w = i + j;
    		System.out.println(w);
    	}
    
    }
    

    那么问题来了,如果我们在//todo那里注入几行代码,能否让我们的1+1=3呢?
    没错,必须可以!

    public class Calc {
    
    	public static void main(String[] args) throws Exception{
    		
    		Class clz = Integer.class.getDeclaredClasses()[0];
    		Field cacheField = clz.getDeclaredField("cache");
    		cacheField.setAccessible(true);
    		Integer[] cache = (Integer[])cacheField.get(clz);
    		cache[130] = 3;
    		
    		Integer i = 1;
    		Integer j = 1;
    		Integer w = i + j;
    		System.out.println(w);
    	}
    
    }
    

    当我们运行上面这段代码时,我们会神奇的发现,没错1+1=3!
    解读:java中的Integer包装类中有一个私有的静态类IntegerCache,该静态类中有一个Integer类型的缓存数组,
    java实例化Integer变量时,会先从这个缓存数组中取对应的值。上面的代码cache[130] = 3;其中下标130就是
    整数2的缓存位置,相当于我们把整数2这个缓存值改成了3。这时我们java的所有Integer类型的变量值为2的全部
    变成了3。造成算术计算混乱。
    然而这个缓存数组具体缓存了哪些值呢,我们循环打印一下即可发现天机,java默认缓存了-128至127这些整数。

    public class Calc {
    
    	public static void main(String[] args) throws Exception{
    		
    		Class clz = Integer.class.getDeclaredClasses()[0];
    		Field cacheField = clz.getDeclaredField("cache");
    		cacheField.setAccessible(true);
    		Integer[] cache = (Integer[])cacheField.get(clz);
    		cache[130] = 3;
    		for(int i=0; i<cache.length; i++){
    			System.out.println("下标为" + i + "的值为" + cache[i]);
    		}
    	}
    
    }
    

    结果输出:

    下标为0的值为-128
    下标为1的值为-127
    下标为2的值为-126
    下标为3的值为-125
    下标为4的值为-124
    下标为5的值为-123
    下标为6的值为-122
    下标为7的值为-121
    下标为8的值为-120
    下标为9的值为-119
    .................
    .................
    .................
    下标为245的值为117
    下标为246的值为118
    下标为247的值为119
    下标为248的值为120
    下标为249的值为121
    下标为250的值为122
    下标为251的值为123
    下标为252的值为124
    下标为253的值为125
    下标为254的值为126
    下标为255的值为127