package wit.test;</p><p>public class Test2<br />{<br />public static void main(String[] args) {<br /> //傳對象<br /> AA a =new AA();<br /> a.n = 10;<br /> System.out.println("調用函數(參數是對象)前:"+a.n);<br /> f(a);<br /> System.out.println("調用函數(參數是對象)後:"+a.n);</p><p> //傳的是基本類型<br /> int n = 10;<br /> System.out.println("調用函數(參數是基本類型int)前:"+n);<br /> f(n);<br /> System.out.println("調用函數(參數是基本類型int)後:"+n);</p><p> Integer nn = new Integer(10);<br /> System.out.println("調用函數(參數是基本類型Integer)前:"+nn);<br /> f(nn);<br /> System.out.println("調用函數(參數是基本類型Integer)後:"+nn);</p><p> //傳的String<br /> String s = new String("ou");<br /> System.out.println("調用函數(參數是String)前:"+s);<br /> f(s);<br /> System.out.println("調用函數(參數是String)後:"+s);</p><p> //傳遞的StringBuffer<br /> StringBuffer sb =new StringBuffer("ouyang");<br /> System.out.println("調用函數(參數是StringBuffer)前:"+sb);<br /> f(sb);<br /> System.out.println("調用函數(參數是StringBuffer)後:"+sb);<br /> //傳的是String[]<br /> String[] ss = new String[3];<br /> ss[0] = "歐";ss[1]="陽";<br /> System.out.println("調用函數(參數是String[])前:"+ss[0]);<br /> f(ss);<br /> System.out.println("調用函數(參數是String[])後:"+ss[0]);</p><p> //傳遞的是int[]<br /> int[] ii = {10,20,30};<br /> System.out.println("調用函數(參數是int[])前:"+ii[0]);<br /> f(ii);<br /> System.out.println("調用函數(參數是int[])後:"+ii[0]);</p><p>}<br />//傳對象<br />public static void f(AA a) {<br /> a.n = 20;<br />}<br />//傳的基本類型<br />public static void f(int n) {<br /> n = 20;<br />}<br />public static void f(Integer n) {<br /> n = 20;<br />}<br />//傳的String[]<br />public static void f(String[] a) {<br /> a[0]="平";<br />}<br />//傳的String<br />public static void f(String a) {<br /> a = "ouyangping";<br />}<br />//傳的int[]<br />public static void f(int a[]) {<br /> a[0] = 20;<br />}<br />//傳的StringBuffer<br />public static void f (StringBuffer sb) {<br /> sb.append("ping");<br />}<br />};<br />class AA<br />{<br />public int n ;<br />};</p><p>
/*************************
* 總結
*************************/
// Java函數參數是值傳遞的。
//. 如果參數是基本類型,函數不能改變參數的值。(包括 String)
//-----傳遞過去的是值傳遞,傳遞的是
//. 如果參數是對象,函數可以改變參數的屬性(包括StringBuffer,int[]等)。
//. 如果參數是對象,函數不能使參數指向新的對象。
//這很好解釋,對於基本類型諸如int,傳遞進去的是存放int值的“記憶體單元”的一個copy,所以函數swap裡面的int和外面的int根本就不是一個東西,當然不能反射出去影響外面
//
//的int。而對於物件類型,我們同樣可以這樣認為,傳遞進去的是存放物件類型的指標的“記憶體單元”一個copy(雖然Java裡面沒有指標的概念,但這並不妨礙我們理解)。這樣,
//
//在swap函數裡面,對其指標本身的值做任何操作當然不會影響外面的Integer,因為interger1和interger2的“記憶體單元”裡面的值是不變的,其指向的物件類型也是沒有變的。
//
//然後這裡需要說明一個問題,就是StringBuffer這種類型的對象了。因為其內容是可以改變的,所以change函數裡面的“指標”通過類似“*”的操作,改變了StringBuffer對象的
//
//本身,就顯而易見了。(StringBuffer對象本身只有一個副本)
//
//然後說C++了,裡面的基本類型的諸如int的值傳遞大家都瞭然於胸,就不在這裡廢話了。然後另一種值傳遞可以稱為指標引用傳遞
,《Core Java 2: Volume I - Fundamentals》中有這樣一段話:
The Java programming language always uses call by value. That means, the method gets a copy of all parameter values. In particular, the method cannot modify the contents of any parameter variables that are passed to it.
Many programming languages (in particular, C++ and Pascal) have two methods for parameter passing: call by value and call by reference. Some programmers (and unfortunately even some book authors) claim that the Java programming language uses call by reference for objects. However, that is false. Because this is such a common misunderstanding, it is worth examining a counterexample in detail.
Let's try to write a method that swaps two employee objects:
public static void swap(Employee x, Employee y) // doesn't work { Employee temp = x; x = y; y = temp; }
If the Java programming language used call by reference for objects, this method would work:
Employee a = new Employee("Alice", . . .); Employee b = new Employee("Bob", . . .); swap(a, b); // does a now refer to Bob, b to Alice?
However, the method does not actually change the object references that are stored in the variables a and b. The x and y parameters of the swap method are initialized with copies of these references. The method then proceeds to swap these copies.
But ultimately, this is a wasted effort. When the method ends, the parameter variables x and y are abandoned. The original variables a and b still refer to the same objects as they did before the method call.
// x refers to Alice, y to Bob Employee temp = x; x = y; y = temp; // now x refers to Bob, y to Alice
程式運行結果:
調用函數(參數是對象)前:10
調用函數(參數是對象)後:20
調用函數(參數是基本類型int)前:10
調用函數(參數是基本類型int)後:10
調用函數(參數是基本類型Integer)前:10
調用函數(參數是基本類型Integer)後:10
調用函數(參數是String)前:ou
調用函數(參數是String)後:ou
調用函數(參數是StringBuffer)前:ouyang
調用函數(參數是StringBuffer)後:ouyangping
調用函數(參數是String[])前:歐
調用函數(參數是String[])後:平
調用函數(參數是int[])前:10
調用函數(參數是int[])後:20
總結一下
有兩種解釋方法、本質是一樣的。
1.從指標的角度考慮、不管你傳什麼都是指標。
傳過來時、在函數中會使用另外一個地址、但是指向的是相同的內容。
如果你只是修改了地址、而這個地址跟你傳進來之前的地址沒有任何關係。
所以不會發生任何變化。但是你修改了指標的內容、你的修改就會發生作用。
2.從引用來說、你傳遞的只是引用本身、並不是引用所指的對象。
你如果只修改引用本身、也不會影響對象的值。
一旦你通過引用修改了對象的值、那麼這個修改會對對象產生影響。