最近在寫代碼的時候出了一個錯誤,由於對值引用理解的不深,將Integer傳入方法中修改,以為傳入后直接修改Integer中的值就不用寫返回值接收了,雖然很快發現了問題,但還是來總結一下
首先是代碼:
public static void main(String[] args){ Integer a1 = 5; updateInteger(a1); System.out.println(a1); } public static void updateInteger(Integer var){ var = 10; }
打印輸出的結果是5,應該是毫無疑問的,可當時為什么我會認為a1應該是10呢?
大概是平時經常obj.integer = number習慣了,所以覺得操作了一個引用就可以修改對象里的值
當我執行var = 10 的值以后,由於jdk1.5自動裝箱的特性,實際情況是等價於執行 var = Integer.valueOf(10);
valueOf()方法 參看源碼 會根據傳入的數值 如果在-128-127之間 就從常量池中獲取一個Integer對象返回
如果不在范圍內 會new Integer(var)返回
那么執行 var = 10以后
當時我天真的以為是操作了那個5變成了10
好了 ,這兩張圖已經足夠說明Java傳參為什么是值傳參而不是引用傳參了
總結一下:
值傳參:將傳入的值拷貝一份 ,比如傳入int a = 5,並不會將變量a的地址傳給方法
又或者傳入對象類型Integer a1 =5 ,a1本身是個引用,傳入方法后不會直接將a1這個引用傳入,而是重新復制一份引用到方法參數中 ,有點繞 不理解? 想一下如果是將a1真實的傳入上述的方法中,那就變成a1 = new Integer(10) ,結果就不一樣了,變成下圖所示,當然這是在JAVA中不可能的
引用傳參:你可以理解為每次都把變量本身真實的傳進去了,不管是個像int a這種引用地址的變量,還是像Integer a1這種引用對象的變量
public static void main(String[] 參數) {
AtomicInteger i=new AtomicInteger(40);
i.intValue();
System.out.println(i);
}
public static void change(AtomicInteger i) {
i.set(55);
}