從bytecode角度來分析String?

Tags: 物件, 結果, 角度,

String物件是不可變的,String物件的其它API返回的String都是new出來的

本文從ByteCode角度解析使用==比較兩個String物件時的情況

工具/原料

IntelliJ IDEA

javap

方法/步驟

先來一段腳手架程式碼

Code:

package chapter5;

/**

* Created by MyWorld on 2016/4/3.

*/

public class StringStudyByByteCode {

public static void main(String[] args) {

String var1 = "StringByByteCode";

String var2 = "StringByByteCode";

System.out.println("var1==var2 :" + (var1 == var2));

}

}

Output:

執行結果:

var1==var2 :true

從bytecode角度來分析String ==的執行結果

可以執行結果是true

現在從位元組碼角度來分析一下返回true的原因

使用javac來編譯剛才的.java檔案

命令:

javac chapter5/StringStudyByByteCode.java

從bytecode角度來分析String ==的執行結果

使用javap來反編譯剛才生成的.class檔案

命令:

javap -v chapter5/StringStudyByByteCode

從bytecode角度來分析String ==的執行結果

來找找程式碼中定義的兩個變數var1和var2

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=4, locals=3, args_size=1

0: ldc #2 // String StringByByteCode

解釋://將#2對應的常量值載入到運算元棧棧頂

//可以看來#2對應的常量值就是“StringByByteCode”

2: astore_1 解釋://將當前運算元棧棧頂的資料賦於變數1,即var1

3: ldc #2 // String StringByByteCode

解釋://將#2對應的常量值載入到運算元棧棧頂

//可以看來#2對應的常量值就是“StringByByteCode”

5: astore_2 解釋://將當前運算元棧棧頂的資料賦於變數2,即var2

6: getstatic #3 // Field java/lang/System.out:

從bytecode角度來分析String ==的執行結果

來看看常量值的#2對應的值是什麼

可以看到常量池中#2的值來自#27

反編譯程式碼中關於#2的資訊:

public class chapter5.StringStudyByByteCode

minor version: 0

major version: 52

flags: ACC_PUBLIC, ACC_SUPER

Constant pool:

#1 = Methodref #12.#26 // java/lang/Object." ":()V

#2 = String #27 // StringByByteCode

從bytecode角度來分析String ==的執行結果

常量值#27對應的值是什麼

可以看到常量池中#27的值為“StringByByteCode”

反編譯程式碼中關於#27的資訊:

#26 = NameAndType #13:#14 // " ":()V

#27 = Utf8 StringByByteCode

#28 = Class #42 // java/lang/System

從bytecode角度來分析String ==的執行結果

通過上面的分析,可以看到

變數var1和var2的值都來自常量池中的#2

對物件使用==操作符時,比較的是記憶體地址

這種情況下,var1==var2就應該是true了

相關問題答案