值傳遞和引用傳遞


值傳遞:傳遞的是實際參數的一個副本,這個值可能是基本類型,也可能是引用類型的地址.

引用傳遞:傳遞的是實際參數的地址的一個副本.

在java中,只有值傳遞.

一.值傳遞

1.基本類型

 1 public class ValueTest {
 2     
 3     public static void main(String[] args) {
 4         int a = 10;
 5         changeVal(a);
 6         System.out.println(a);
 7     }
 8     
 9     public static void changeVal(int a){
10         a += 10;
11     }
12     
13 }

上面的demo輸出的是10,而不是20。為什么?

①.程序運行時,main方法先入棧,然后給變量a分配內存。

②.當運行到changeVal(a);時,changeVal()方法入棧。當方法入棧時,會給局部變量和形參變量(a)分配內存.

   即在changeVal方法棧里面,也有一個名為a,值為10的變量。

③.由於a+=10;是在changeVal方法棧里面運行的,所以只會改變changeVal方法棧里面的a值,而不會改變main方法棧里面的a值。如下圖

 

2.引用類型

引用類型也是值傳遞,不過這個"值"指的是對象的內存地址.

 1 public class ValueTest {
 2     
 3     public static void main(String[] args) {
 4         StringBuilder builder = new StringBuilder("hello");
 5         changeVal(builder);
 6         System.out.println(builder);
 7     }
 8     
 9     public static void changeVal(StringBuilder builder){
10         builder.append(" world");
11     }
12     
13 }

輸出是hello world,可見builder的值是改變了.

與基本類型不一樣,主要是StringBuilder是引用類型。因此new StringBuilder("hello")的內存是分配在堆區。而在棧區的變量(builder)只保存一個地址(假設為0x345),如下圖:

因此,main和changeVal兩個方法棧的builder變量都指向了同一塊內存。故當changVal方法中改變builder的值,main中的builder也會變化。

 

3."特殊的"String

 1 public class ValueTest {
 2     
 3     public static void main(String[] args) {
 4         String str = "hello";
 5         changeVal(str);
 6         System.out.println(str);
 7     }
 8     
 9     public static void changeVal(String str){
10         str+=" world";
11     }
12     
13 }

上面的demo輸出的是:hello,而不是hello world。str記錄了對象的地址,那么str的值應該也被改變了才對?

這跟String的"特性"有關,String會被存放在字符串常量池,而且String是不可被改變的(final).

①.在第10行設個斷點,當執行到這行的時候,由上面的分析可知,main()和changeVal()方法中的str都指向了常量池中的"hello"字符串。

②.執行str+=" world"時,由於String是不可變的,所以不可能直接在"hello"上做修改。這時會在常量池中新增一個"hello world"的字符串,並將地址傳給changeVal()方法棧中的str.

③.因此changeVal()方法中的str指向了新增的"hello world"字符串,而main方法中的str還是指向原來的"hello"。所以輸出"hello".

 

二.引用傳遞

引用傳遞,傳遞的是實際參數的地址.

如下圖,有變量builder,值指向了堆內存地址(假設為0x456)。但是builder變量本身也有地址(假設為0x123)。傳遞的時候,傳的就是0x123.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM