忽然想到這個問題,而後作了下實驗,下面以Integer來說解,其餘的忽略:java
import java.util.Iterator; /** * Created by lili on 15/9/24. */ public class TestNew { public static void main(String args[]){ Integer i1 = 10; Integer i2 = 20; System.out.println(i1 + " " + i2); change(i1,i2); System.out.println(i1 + " " + i2); String s1 = new String("s1"); String s2 = new String("s2"); System.out.println(s1 + " " + s2); change(s1, s2); System.out.println(s1 + " " + s2); StringBuilder sb1 = new StringBuilder("sb1"); StringBuilder sb2 = new StringBuilder("sb2"); System.out.println(sb1 + " " + sb2); change(sb1,sb2); System.out.println(sb1 + " " + sb2); } public static void change(Integer i1, Integer i2){ i1 = 100; i2 = 200; } public static void change(String i1, String i2){ i1 = "ii1"; i2 = "i22"; } public static void change(StringBuilder i1, StringBuilder i2){ i1.append("sbsbsb1"); i2.append("sbsbsb2"); } }
運行結果:app
10 20
10 20
s1 s2
s1 s2
sb1 sb2
sb1sbsbsb1 sb2sbsbsb2
Process finished with exit code 0
事實證實,只有StringBuilder是引用傳遞,其餘的仍是值傳遞。優化
按照常理,應該傳遞的是對象的地址,難道這裏是由於作了自動裝箱和拆箱,編譯器幫你作了這個致使最後是值傳遞了?ui
帶着這個問題首先去看了class文件的反編譯代碼:spa
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // public class TestNew { public TestNew() { } public static void main(String[] var0) { Integer var1 = Integer.valueOf(10); Integer var2 = Integer.valueOf(20); System.out.println(var1 + " " + var2); change(var1, var2); System.out.println(var1 + " " + var2); String var3 = new String("s1"); String var4 = new String("s2"); System.out.println(var3 + " " + var4); change(var3, var4); System.out.println(var3 + " " + var4); StringBuilder var5 = new StringBuilder("sb1"); StringBuilder var6 = new StringBuilder("sb2"); System.out.println(var5 + " " + var6); change(var5, var6); System.out.println(var5 + " " + var6); } public static void change(Integer var0, Integer var1) { var0 = Integer.valueOf(100); var1 = Integer.valueOf(200); } public static void change(String var0, String var1) { var0 = "ii1"; var1 = "i22"; } public static void change(StringBuilder var0, StringBuilder var1) { var0.append("sbsbsb1"); var1.append("sbsbsb2"); } }
源代碼顯示並無作值傳遞的優化,由於若是作了,應該change中的參數會改成int,這樣一來Integer對象會自動拆裝爲int進行值傳遞,一種自動裝卸拆箱的代碼示例以下:debug
Integer integer = 11; integer += 9; /* Integer integer = Integer.valueOf(11);//自動裝箱 integer = Integer.valueOf((integer.intValue() + 9));//自動拆箱再裝箱 */
那到底是什麼緣由呢?3d
帶着這個問題,對程序進行了debug,看看傳遞的是不是對象地址。code
進入change方法後,看地址的變化對象
發現傳入的是地址值,change參數的i1和i2的對象指向Integer@417和Integer@418,說明指向和傳入參數的同一個對象,傳入的是地址。blog
接着執行方法change程序:
執行改變i1的值時,此時i1指向的對象改成了Integer@427,至此能夠充分說明不是自動裝箱和拆箱的問題了,可是究其緣由,個人理解仍是和這個相關,由於執行到這一步的時候是i1 = 100;可是具體編譯器優化後作了自動裝箱處理,var0 = Integer.valueOf(100);因此i1指向了Integer.valueOf(100)這個新產生的對象,因此最後和值傳遞的效果同樣,不會改變調用該方法的參數的值。