如何編程實現 2 + 2 = 5?
Write a program that makes 2 + 2 = 5,看到這個題目,感覺很新穎,第一個答案就是用Java實現的。用上了Java中的整型實例池的概念。以前只看到過實例池導致兩個對象的指針相同的問題,即
Integer a = new Integer(2); Integer b = new Integer(2); System.out.print(a == b);
上面的代碼最終輸出的是true,按照Java對象的申請原則來說,這里應該是false才對。正是因為JVM在實現的時候,默認生成了一些 Integer對象的實例,當需要的實例是池子中已經存在的數值時,直接返回已經生成的對象的引用,不必新構造對象。這樣可以極大減少實例數目和程序運行 性能。
而這個題目是將池子中的對象的內容進行了修改,最終使得取回的實例的值發生了改變。這樣其實很危險的,如果在正式運行程序的業務代碼之前,做這個修改,那么整個程序的運行邏輯將產生混亂。
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); } }
上面是具體的代碼,最終輸出的結果為5,作者給出的解釋為:
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.
利用緩存的讀寫接口,將4這個實例的緩存對象的指針改為指向5的實例對象了,這樣,當應用程序取出4時,實際上返回的是5的引用,打印出來的也就是5了。
來自: shentar