原出处是国外某论坛某帖子中楼主提问:如何让1+1=3?
于是出现了各种语言实现的各种机制的答案,当然其中也包括直接用字符串输出"1+1=3"...
最后被采纳的是用Java语言实现的答案。
以下是答案:
public static void main(String[] args) throwsIllegalAccessException, NoSuchFieldException {
Class cache= Integer.class.getDeclaredClasses()[0];
Field c= cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array=(Integer[]) c.get(cache);
array[130] = array[131];
System.out.printf("%d", 1 + 1);
}
作者解释:
You need to change it even deeper than you can typically access.
Note that this is designed for Java 6 with no funky parameters passed in on the JVM that would otherwise change the IntegerCache.
Deep within the Integer class is a Flyweight of Integers.This is an array of Integers from 128 to +127. cache[132] is the spot where 4 would normally be. Set it to 5.
这样思路已经很明确了。
Integer.class.getDeclaredClasses()[0]指向IntegerCache类,其cache域在静态初始化块内进行初始化,缓存-128到127,由此可知cache[130]==2。
static{//high value may be configured by property
int h = 127;
String integerCacheHighPropValue=sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {int i =parseInt(integerCacheHighPropValue);
i= Math.max(i, 127);//Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));
}
high=h;
cache= new Integer[(high - low) + 1];int j =low;for(int k = 0; k < cache.length; k++)
cache[k]= new Integer(j++);
}
于是写出了如下代码,只可惜运行结果仍然是2:
public static void main(String[] args) throwsIllegalAccessException, NoSuchFieldException {
Class cache= Integer.class.getDeclaredClasses()[0];
Field c= cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array=(Integer[]) c.get(cache);
array[130] = array[131];
System.out.println(1+1);
}
问题就出在printf还是println。
参考println的方法声明,作者对于不同的基本类型都提供了overwrite,而printf并没有为基本类型提供方法。
wKiom1P1x5uiJ_7FAADt9PjOSaM217.jpg
wKiom1P1yGeRfS2nAAD6dtUCDzM911.jpg
虽说printf("%d",1+1)相当于System.out.println(String.format("%d", 1 + 1));
但问题的本质还是在于println(1+1)的结果仍是基本类型,并没有进行装箱。
即,System.out.println((Integer)1+1);的结果为3.