Java:傳值仍是傳引用?

這是一個Java的經典問題,大部分人從C,C++語言入門,C語言有三種傳遞方式:值傳遞,地址傳遞和引用傳遞。詳細的對C語言指針,引用的我我的的理解,見連接html

Java全部操做都是傳值操做!都是傳值操做!都是傳值操做!重要的事情說三遍。java

疑問?那爲何別人講的時候都是說,java的基本數據類型都是傳值,全部的自定義數據(類的對象)都是傳引用??函數

很簡單,由於這樣好理解,意思是說:「同窗們,若是咱們把一個基本數據類型的值(變量)傳遞給一個函數的形參,那麼不管咱們對這個變量怎麼操做,函數運行完以後,並不會改變這個變量的值!(到這裏都是對的)可是若是咱們把一個類的實例(對象)做爲參數傳遞給函數,那麼咱們在函數裏面對這個對象的改變,會實際地改變這個對象的值!(這裏就不徹底正確了)」。post

對於Java的對象與引用的理解,請參見:淺談Java中的對象和引用。我這裏簡單說一下Person person = new Person("張三"),這裏面new Person("張三")是類Person的實例(或者說是對象),person是這個實例(對象)的引用。this

Java的參數傳遞都是值傳遞!!!url

先貼一篇博文:理解Java中的引用傳遞和值傳遞,若是你以爲這我的講的頗有道理,那麼你是麻瓜(哇!馬老師附體!)。我先不解釋,去看下這篇博文的1樓評論!spa

咱們先定義,什麼是值傳遞,什麼是引用傳遞。.net

值傳遞:方法調用時,實際參數把它的值的副本傳遞給對應的形式參數。特色:此時內存中存在兩個相等的基本類型,即實際參數和形式參數後面方法中的操做都是對形參這個值的修改,不影響實際參數的值指針

引用傳遞:方法調用時,實際參數的引用(地址,而不是參數的值)被傳遞給方法中相對應的形式參數,函數接收的是原始值的內存地址;特色:在方法執行中,形參和實參內容相同,指向同一塊內存地址,方法執行中對引用的操做將會影響到實際對象code

值傳遞實在是太簡單了,你們應該都容易理解,既然傳遞的是實際參數的副本,那麼更改這個副本,跟原來的變量沒有一點關係。

可是對於引用傳遞,通常的支持引用的例子我也不說了。看一個稍微特殊的例子:若是咱們把下面的例子理解爲引用傳遞,輸出應該是: LI Si 纔對!由於zhangsan這個(new Person("ZHANG San")的)引用指向了新的對象!但實際結果是zhangsan這個引用指向的對象的名字並無變!

 1 public class ValueOrRef {
 2     public static void main(String[] args) {
 3         Person zhangsan = new Person("ZHANG San");
 4         changePerson(zhangsan);
 5         zhangsan.printName();
 6     }
 7     public static void changePerson(Person person){
 8         person = new Person("LI Si");
 9     }
10 }
11 
12 class Person {
13     String name = "default";
14     public Person(String name) {
15         this.name = name;
16     }
17     public void changeName(String name){
18         this.name = name;
19     }
20     void printName() {
21         System.out.println(this.name);
22     }
23 }

因此這裏,咱們把這種傳遞也理解爲」值傳遞「只不過這裏的值,是一個」引用」的值!也就是咱們把實際參數(一個引用)拷貝一份賦值給形式參數,形式參數進行操做。當形式參數對自己的對象進行了變更操做,這裏的效果跟引用傳遞是相同的。可是一旦給形式參數進行賦值類型的操做,這個賦值操做並不會像C語言的引用那樣,把這個賦值的效果反映在函數運行結束以後!!

總結:不要糾結與值傳遞與引用傳遞的概念了,咱們明白函數執行的過程就行了!爲了更好地理解整個運行過程的變化,請參考:Java:按值傳遞仍是按引用傳遞詳細解說(其中有圖片演示,很清楚)。

相關文章
相關標籤/搜索