這是一個挺有意思的討論話題。
如果你運行下面的代碼:
Integer a = 1000, b = 1000; System.out.println(a == b);//1Integer c = 100, d = 100; System.out.println(c == d);//2
你會得到
falsetrue
基本知識:我們知道,如果兩個引用指向同一個對象,用 == 表示它們是相等的。如果兩個引用指向不同的對象,用 == 表示它們是不相等的,即使它們的內容相同。
因此,後面一條語句也應該是 false 。
這就是它有趣的地方了。如果你看去看 Integer.java 類,你會發現有一個內部私有類,IntegerCache.java,它緩存了從 - 128 到 127 之間的所有的整數對象。
所以事情就成了,所有的小整數在內部緩存,然後當我們聲明類似——
Integer c = 100;
的時候,它實際上在內部做的是:
Integer i = Integer.valueOf(100);
現在,如果我們去看 valueOf() 方法,我們可以看到
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i return IntegerCache.cache\[i + (-IntegerCache.low)\]; return new Integer(i); }
如果值的範圍在 - 128 到 127 之間,它就從高速緩存返回實例。
所以…
Integer c = 100, d = 100;
指向了同一個對象。
這就是為什麼我們寫
System.out.println(c == d);
我們可以得到 true。
現在你可能會問,為什麼這裡需要緩存?
合乎邏輯的理由是,在此範圍內的 「小」 整數使用率比大整數要高,因此,使用相同的底層對象是有價值的,可以減少潛在的內存佔用。
然而,通過反射 API 你會誤用此功能。
運行下面的代碼,享受它的魅力吧
public static void main(String\[\] args) throws NoSuchFieldException, IllegalAccessException {Class cache = Integer.class.getDeclaredClasses()\[0\]; //1 Field myCache = cache.getDeclaredField("cache"); //2 myCache.setAccessible(true);//3 Integer\[\] newCache = (Integer\[\]) myCache.get(cache); //4 newCache\[132\] = newCache\[133\]; //5 int a = 2; int b = a + a; System.out.printf("%d + %d = %d", a, a, b); // }
這裡小編準備了幾十套阿里、頭條、騰訊和美團等公司2020年金九銀十的面試題,把技術點整理成了視頻+文檔(總計20G,實際上比預期多花了不少精力),包含知識脈絡 + 諸多細節,由於篇幅有限,這裡以圖片的形式給大家展示一部分。
這份資料尤其適合:
沒有工作經驗,但基礎非常紮實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的。具有一定工作經驗的,但面對目前流行的技術不知從何下手,需要快速提升核心競爭力的人群。在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的可以報名。想了解「一線網際網路公司」最新招聘需求/技術要求,對比找出自身的長處和弱點所在,評估自己在現有市場上的競爭力如何;做了幾年Java開發,但還沒形成系統的Java知識體系,缺乏清晰的提升方向和學習路徑的程式設計師。相信它會給大家帶來很多收穫。(更全的內容和資料,在文末獲取)
資料獲取方式:
轉發加關注後臺私信電子書 免費獲取!