如何編程實現 2 + 2 = 5?

jopen 10年前發布 | 14K 次閱讀 編程

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!