原文地址 :http://blog.sina.com.cn/jacktee
先來看下面這三段代碼:
//Example1: public class Example1 { static void check(int a) { a++; } public static void main(String[]args) { int x=10; check(x); System.out.println(“Example1.x=”+x);} } //Example2: public class Example2 { static void check(StringBuffer obj) { obj.append(“JAVA”); } public static void main(String[]args) { StringBuffer x=new StringBuffer(“Hello ”); check(x); System.out.println(“Example2.x=”+x); } } //Example3: Public class Example3 { static void check(String obj) { obj=“JAVA”; } public static void main(String[]args) { String x=”Hello ”; check(x); System.out.println(“Example3.x=”+x); } } 編譯並運行上述代碼,結果如下: Example1.x=10 Example2.x=Hello JAVA Example3.x=Hello
解釋:
傳值傳引用都不夠准確,可以理解成傳
引用變量的副本值。引用變量分為
字面值引用變量(即基本數據類型引用變量)和
對象引用變量 。 詳情需要了解數據類型使用機制和堆棧的概念:http://www.cnblogs.com/alexlo/archive/2013/02/21/2920209.html
對象引用變量:即普通java對象的引用變量 ,如 String a = "abc" , a就是對象引用變量。java 是不能直接操作對象的,只能通過對“對象引用的操作”來操作對象。而對象的引用的表示就是對象變量。可以多個對象引用變量指向同一個對象。
字面值引用變量:即普通數據類型的引用變量 ,如 int b = 1 , b就是
字面值引用變量。可以有多個字面值引用變量指向同一字面值,但其中一個引用修改字面值,不會影響另一個引用字面值,這點要與對象引用區別開。
Example1的結果是最容易理解的,因為此時向方法check(int a) 傳遞的是一個整型變量,而整型變量是基本數據類型的一種。當向一個方法傳遞基本數據類型時(基本數據類型包 括 byte,int,short,char,float,double以及boolean),傳遞的只是該數據內容的一個副本(確切可以理解成字面值引 用變量的副本),因此無論方法針對該副本值做怎樣的改變(或者是說對字面值),都不會影響到被傳入的數據本身。
Example2的結果也是比較容易理解的,因為此時向方法check(StringBuffer obj)傳遞的是一個StringBuffer變量,這個變量是對象型數據類型的一種。當向一個方法傳遞對象型數據類型(包括String, StringBuffer,類對象引用,接口引用和數組等)時,傳遞的是該數據對象的某個引用變量(的副本)而不是對象內容本身,因此,在將引用變量x傳入方法時,obj和x便同時對原來x所引用的對象(這個對象的內容是”Hello ”)具有了引用關系,也就是說,obj和x都是對象(即”Hello ”)的引用,由於JAVA對於對象的訪問是通過訪問對象的引用來完成的,因此,當方法對obj的引用對象內容進行改變時,實際上也是在針對x所引用的對象的內容進行改變,這自然導致了讀者所看到的結果。
Example3 , 和Excample2 一樣,傳遞的是String 對象的引用的副本值,所以
obj和x都是對象(即”Hello ”)的引用。
關鍵點,String 是final 不可變的,即String類型對象是不可變的,當然也就不可以通過引用對該對象進行任何改變了。而 obj=“JAVA” 這句,並沒有改變“HELLO” 這個對象,而是將obj這個引用變量重新指向新的對象。