熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java迷題:等於還是不等於?

2013-11-23 19:52:01  來源: Java高級技術 
表面上看來這只是一些基礎的問題當真正的了解了以後你就會發現原來是這麼一回事!下文是幾道Java謎題不仔細分析就會犯錯哦

  等於還是不等於?

  看來看下面的一段代碼

  代碼片段

  public static void main(final String[] args) { Integer a = new Integer(); Integer b = ; Systemoutprintln(a == b); }

  這段代碼的輸出是什麼?相信很多人都會很容易的猜到false因為ab兩個對象的地址不同==比較時是false恭喜你答對了

  再看下面的一段代碼

  代碼片段

  public static void main(final String[] args) { Integer a = ; Integer b = ; Systemoutprintln(a == b); }

  你可能會回答這沒什麼不一樣啊所以還是false很遺憾如果你執行上面的一段代碼結果是true

  上面的代碼可能讓你有些意外那好吧再看看下面的這段代碼

  代碼片段

  public static void main(final String[] args) { Integer a = ; Integer b = ; Systemoutprintln(a == b); }

  結果是true嗎?很遺憾如果你執行上面的一段代碼結果是false

  感到吃驚嗎?那最後再看下面的一段代碼

  代碼片段

  public static void main(final String[] args) { Integer a = IntegervalueOf(); Integer b = ; Systemoutprintln(a == b); }

  最後的結果可能你已經猜到了是true

  為什麼會這樣?

  現在我們分析一下上面的代碼可以很容易的看出這一系列代碼的最終目的都是用==對兩個對象進行比較Java中如果用==比較兩個對象結果為true說明這兩個對象實際上是同一個對象false說明是兩個對象

  現在我們來看看為什麼會出現上面的現象

  我們先看代碼片段最後的運行結果是true說明ab兩個對象實際上是同一個對象但是a對象是通過調用Integer的valueOf方法創建的而b對象是通過自動裝箱創建出來的怎麼會是同一個對象呢?難道問題在字節碼那裡畢竟Java程序是依靠虛擬器運行字節碼來實現的

  通過jdk中自帶的工具javap解析字節碼核心的部分摘取如下

  : bipush : invokestatic #; //Method java/lang/IntegervalueOf:(I)Ljava/lang/Integer; : astore_ : bipush : invokestatic #; //Method java/lang/IntegervalueOf:(I)Ljava/lang/Integer;

  代碼中我們只調用了一次IntegervalueOf方法但是字節碼中出現了兩次對IntegervalueOf方法的調用那麼另一次是哪裡呢?只可能在自動裝箱時調用的因此這段代碼實際上等價於

  public static void main(final String[] args) { Integer a = IntegervalueOf(); Integer b = IntegervalueOf(); Systemoutprintln(a == b); }

  現在問題就簡單了看jdk源代碼查看valueOf方法的具體實現

  public static Integer valueOf(int i) { final int offset = ; if (i >= && i <= ) { // must cache return IntegerCachecache[i + offset]; } return new Integer(i); }

  看到這兒上面的代碼就很明確了對於的數字valueOf返回的是緩存中的對象所以兩次調用IntegervalueOf()返回的都是同一個對象

  我們再先看代碼片段根據上面的分析代碼片段實際上等價於以下代碼

  public static void main(final String[] args) { Integer a = IntegervalueOf(); Integer b = IntegervalueOf(); Systemoutprintln(a == b); }

  由於不在范圍內所以兩個對象都是通過new Integer()的方式創建的所以最後結果為false

  片段和片段就不做具體分析了相信讀者可以自行分析

  最後請大家思考一下問題通過上面的分析了解到整數的自動裝箱是通過IntegervalueOf(int number)實現的那麼自動拆箱是如何實現的呢?


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27590.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.