java基礎資料型別 (Elementary Data Type)傳遞與引用傳遞區別

來源:互聯網
上載者:User

標籤:csdn   初始化   對象狀態   print   temp   必須   通過   list   targe   

文章轉載自  zejian的部落格http://blog.csdn.net/javazejian/article/details/51192130

java的值傳遞和引用傳遞在面試中一般都會都被涉及到,今天我們就來聊聊這個問題,首先我們必須認識到這個問題一般是相對函數而言的,也就是java中的方法參數,那麼我們先來回顧一下在程式設計語言中有關參數傳遞給方法(或函數)的兩個專業術語:

  • 按值調用(call by value)

  • 按引用調用(call by reference)

所謂的按值調用表示方法接收的是調用著提供的值,而按引用調用則表示方法接收的是調用者提供的變數地址(如果是C語言的話來說就是指標啦,當然java並沒有指標的概念)。這裡我們需要注意的是一個方法可以修改傳遞引用所對應的變數值,而不能修改傳遞值調用所對應的變數值,這句話相當重要,這是按值調用與引用調用的根本區別,當然如果還不理解,沒關係,下面就要圖文並茂的徹底分析啦。

前面我們說過java中並不存在引用調用,這點是沒錯的,因為java程式設計語言確實是採用了按值調用,即call by value。也就是說方法得到的是所有參數值的一個拷貝,方法並不能修改傳遞給它的任何參數變數的內容。下面我們來看一個例子:

 

package com.zejian.test;  /**  * java中的按值調用  * @author zejian  */  public class CallByValue {            private static int x=10;            public static void updateValue(int value){          value = 3 * value;      }            public static void main(String[] args) {          System.out.println("調用前x的值:"+x);          updateValue(x);          System.out.println("調用後x的值:"+x);      }        }  

  

運行程式,結果如下:

調用前x的值:10

調用後x的值:10

可以看到x的值並沒有變化,接下來我們一起來看一下具體的執行過程:

 

分析:

1)value被初始化為x值的一個拷貝(也就是10)

2)value被乘以3後等於30,但注意此時x的值仍為10!

3)這個方法結束後,參數變數value不再使用,被回收。

結論:當傳遞方法參數類型為基礎資料型別 (Elementary Data Type)(數字以及布爾值)時,一個方法是不可能修改一個基礎資料型別 (Elementary Data Type)的參數。

當然java中除了基礎資料型別 (Elementary Data Type)還有引用資料類型,也就是對象引用,那麼對於這種資料類型又是怎麼樣的情況呢?我們還是一樣先來看一個例子:

      聲明一個User物件類型:

package com.zejian.test;  public class User {      private String name;      private int age;      public User(String name, int age) {          this.name=name;          this.age=age;      }      public String getName() {          return name;      }      public void setName(String name) {          this.name = name;      }      public int getAge() {          return age;      }      public void setAge(int age) {          this.age = age;      }  }  

  執行類如下:

package com.zejian.test;  /**  * java中的按值調用  * @author zejian  */  public class CallByValue {      private static User user=null;      public static void updateUser(User student){          student.setName("Lishen");          student.setAge(18);      }                  public static void main(String[] args) {          user = new User("zhangsan",26);          System.out.println("調用前user的值:"+user.toString());          updateUser(user);          System.out.println("調用後user的值:"+user.toString());      }  }  

  

運行結果如下:

調用前user的值:User [name=zhangsan, age=26]

調用後user的值:User [name=Lishen, age=18]

很顯然,User的值被改變了,也就是說方法參數類型如果是參考型別的話,參考型別對應的值將會被修改,下面我們來分析一下這個過程:

過程分析:

1)student變數被初始化為user值的拷貝,這裡是一個對象的引用。

2)調用student變數的set方法作用在這個引用對象上,user和student同時引用的User對象內部值被修改。

3)方法結束後,student變數不再使用,被釋放,而user還是沒有變,依然指向User對象。

結論:當傳遞方法參數類型為引用資料類型時,一個方法將修改一個引用資料類型的參數所指向對象的值。

雖然到這裡兩個資料類型的傳遞都分析完了,也明白的基礎資料型別 (Elementary Data Type)的傳遞和引用資料類型的傳遞區別,前者將不會修改原資料的值,而後者將會修改引用所指向對象的值。可通過上面的執行個體我們可能就會覺得java同時擁有按值調用和按引用調用啊,可惜的是這樣的理解是有誤導性的,雖然上面引用傳遞表面上體現了按引用調用現象,但是java中確實只有按值調用而沒有按引用調用。到這裡估計不少人都蒙逼了,下面我們通過一個反例來說明(回憶一下開頭我們所說明的按值調用與按引用調用的根本區別)。

package com.zejian.test;  /**  * java中的按值調用  * @author zejian  */  public class CallByValue {      private static User user=null;      private static User stu=null;            /**      * 交換兩個對象      * @param x      * @param y      */      public static void swap(User x,User y){          User temp =x;          x=y;          y=temp;      }                  public static void main(String[] args) {          user = new User("user",26);          stu = new User("stu",18);          System.out.println("調用前user的值:"+user.toString());          System.out.println("調用前stu的值:"+stu.toString());          swap(user,stu);          System.out.println("調用後user的值:"+user.toString());          System.out.println("調用後stu的值:"+stu.toString());      }  }  

  

我們通過一個swap函數來交換兩個變數user和stu的值,在前面我們說過,如果是按引用調用那麼一個方法可以修改傳遞引用所對應的變數值,也就是說如果java是按引用調用的話,那麼swap方法將能夠實現資料的交換,而實際運行結果是:

 

調用前user的值:User [name=user, age=26]

調用前stu的值:User [name=stu, age=18]

調用後user的值:User [name=user, age=26]

調用後stu的值:User [name=stu, age=18]

我們發現user和stu的值並沒有發生變化,也就是方法並沒有改變儲存在變數user和stu中的對象引用。swap方法的參數x和y被初始化為兩個對象引用的拷貝,這個方法交換的是這兩個拷貝的值而已,最終,所做的事都是白費力氣罷了。在方法結束後x,y將被丟棄,而原來的變數user和stu仍然引用這個方法調用之前所引用的對象。

這個過程也充分說明了java程式設計語言對對象採用的不是引用調用,實際上是對象引用進行的是值傳遞,當然在這裡我們可以簡單理解為這就是按值調用和引用調用的區別,而且必須明白即使java函數在傳遞引用資料類型時,也只是拷貝了引用的值罷了,之所以能修改引用資料是因為它們同時指向了一個對象,但這仍然是按值調用而不是引用調用。

總結:

    • 一個方法不能修改一個基礎資料型別 (Elementary Data Type)的參數(數值型和布爾型)。

    • 一個方法可以修改一個引用所指向的對象狀態,但這仍然是按值調用而非引用調用。

    • 上面兩種傳遞都進行了值拷貝的過程。

java基礎資料型別 (Elementary Data Type)傳遞與引用傳遞區別

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.