問號臉為什麼 Java 中1000==1000 為 false而 100==100 為 true

2020-12-16 酷扯兒

本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫

為什麼 Java 中「1000==1000」為false,而」100==100「為true?這是一個挺有意思的討論話題。

如果你運行下面的代碼:

Integer a = 1000, b = 1000; System.out.println(a == b);//1 Integer 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); // }

相關焦點

  • java基本數據類型的自動裝箱、自動拆箱
    大家學習java時,一般都是會先去學習java的八種基本數據類型。他們分別是:byte、short、int、long、float、double、boolean、char。為什麼結果是這樣的呢。這裡就涉及到了java基本數據類型的自動裝箱和自動拆箱了。像上面代碼中「Integer b = 5;」這句就會用到自動裝箱,會把基本數據類型的int值5自動封裝成一個Integer類型的對象。
  • 從0到100萬很難,但100萬到1000萬很容易,為什麼?
    對於大多數普通人而言,想要擁有100萬存款,幾乎是一件難如登天的事情。當然了,對於某些精英來說的話,或許100萬並不是什麼大數字,畢竟人家的年薪都有可能遠不止這個數。網上有人說過,那便是普通人從零到100萬,這是一個最難的過程。
  • 新手編程:Java多線程中Thread與Runnable的區別
    Java多線程中Thread與Runnable的區別定義extends Thread子類繼承Thread具備多線程能力,可以實現多線程;啟動線程的方法:①創建子類對象;import java.io.IOException;import java.net.MalformedURLException;import java.net.URL;//練習網絡下載圖片public
  • 牛津大學- 雅思判斷題 True False Not Given Question
    In this lesson, you're going to learn how to complete true/false/not given, and yes/no/not given questions in the IELTS reading exam.歡迎來到牛津大學在線英語課堂。在本節課程中,你將學習如何完成雅思考試中的判斷正誤題目。
  • Java從零開始學 - 第25天:掌握JUC中的阻塞隊列
    本文內容掌握Queue、BlockingQueue接口中常用的方法介紹6中阻塞隊列,及相關場景示例重點掌握4種常用的阻塞隊列Queue接口隊列是一種先進先出(FIFO)的數據結構,java中用Queue接口來表示隊列。
  • Java是如何實現Future模式的?萬字詳解!
    ,說明異步任務執行成功,此時設置ran標誌為true ran = true; } catch (Throwable ex) { result = null;// 異步任務執行過程拋出異常,此時設置ran標誌為false
  • Java 中 Comparable 和 Comparator 比較
    此外,「實現Comparable接口的類的對象」可以用作「有序映射(如TreeMap)」中的鍵或「有序集合(TreeSet)」中的元素,而不需要指定比較器。為什麼可以不實現 equals(Object obj) 函數呢? 因為任何類,默認都是已經實現了equals(Object obj)的。 Java中的一切類都是繼承於java.lang.Object,在Object.java中實現了equals(Object obj)函數;所以,其它所有的類也相當於都實現了該函數。
  • 一文搞懂 Java 中的枚舉,寫得非常好!
    創建enum時,編譯器會為你生成一個相關的類,這個類繼承自 java.lang.Enum。green equals Size.MIDDLE: falsegreen equals 1: falsegreen == Color.BLUE: false 枚舉的特性枚舉的特性,歸結起來就是一句話:除了不能繼承,基本上可以將 enum看做一個常規的類。
  • java中 時間如何計算 - CSDN
    在本教程中,我們向您展示2個示例來計算Java中的日期/時間差: 手動時間計算。 喬達時間圖書館。% 60; long diffMinutes = diff / (60 * 1000) % 60; long diffHours = diff / (60 * 60 * 1000) % 24; long diffDays = diff / (24 * 60 * 60 * 1000); System.out.print(diffDays + " days, "); System.out.print
  • JAVA8 新特性詳解
    );}};formula.calculate(100); // 100.0formula.sqrt(16); // 4.0二、Lambda 表達式我們知道System類中有一個PrintStream的實例為out,引用該實例方法:System.out::println:public class Main {public static void main(String[] args) {LambdaTest2 lt1 = s-
  • 【枚舉】用好 Java 中的枚舉,真的沒有那麼簡單!
    」1.概覽在本文中,我們將看到什麼是 Java 枚舉,它們解決了哪些問題以及如何在實踐中使用  Java 枚舉實現一些設計模式。enum關鍵字在 java5 中引入,表示一種特殊類型的類,其總是繼承java.lang.Enum類,更多內容可以自行查看其官方文檔。
  • Java並發編程系列20|StampedLock源碼解析
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫本文為何適原創並發編程系列第 20 篇,文末有本系列文章匯總。state原始狀態為 //...0001 0000 0000獲取寫鎖 //...0001 1000 0000釋放寫鎖次數加1 //...0010 0000 0000獲取寫鎖 // ...0010 1000 0000
  • 為什麼我有100萬個粉絲,也難養活自己?「小丹尼」
    很多人都聽說過Kevin Kelly提出的「1000個鐵桿粉絲」(1000 True Fans)定律,簡單粗暴的理解就是:只要你有1000個鐵桿粉絲,那你就可以基本養活自己。但是我又發現,我認識很多內容創作者對這句話不以為然:「這句話就是扯淡!為啥我都1萬、10萬,甚至快100萬粉絲了,還不太能只靠做內容養活自己呢?」
  • JAVA-新手入門:JAVA資料庫基本操作指南
    java 資料庫基本操作  1、java資料庫操作基本流程  2、幾個常用的重要技巧:  ·可滾動、更新的記錄集  ·批量更新  ·事務處理java資料庫操作基本流程:取得資料庫連接 - 執行sql語句 - 處理執行結果 - 釋放資料庫連接基礎視頻有挺多的你是看你的學習欲望!!!!
  • 深入分析Java虛擬機堆和棧及OutOfMemory異常產生原因
    :JDK1.6中會輸出false:JDK1.7中輸出true:JDK1.8中也會輸出true:intern()方法jdk1.6及之前的版本中:調用String.intern()方法,會先去常量池檢查是否存在當前字符串,如果不存在,則會在方法區中創建一個字符串,而new String("")方法創建的字符串在堆裡面,兩個字符串的地址不相等
  • Java枚舉用法詳解
    概念enum 的全稱為 enumeration, 是 JDK 1.5 中引入的新特性。在Java中,被 enum 關鍵字修飾的類型就是枚舉類型。形式如下:enum Color { RED, GREEN, BLUE }如果枚舉不添加任何方法,枚舉值默認為從0開始的有序數值。