這是一個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:按值傳遞仍是按引用傳遞詳細解說(其中有圖片演示,很清楚)。