值傳遞:(形式參數類型是基本數據類型):方法調用時,實際參數把它的值傳遞給對應的形式參數,形式參數只是用實際參數的值初始化自己的存儲單元內容,是兩個不同的存儲單元,所以方法執行中形式參數值的改變不影響實際參數的值。
引用傳遞:(形式參數類型是引用數據類型參數):也稱為傳地址。方法調用時,實際參數是對象(或數組),這時實際參數與形式參數指向同一個地址,在方法執行中,對形式參數的操作實際上就是對實際參數的操作,這個結果在方法結束后被保留了下來,所以方法執行中形式參數的改變將會影響實際參數。
//按值傳遞
public class shiyan { //先創建一個更改變量的函數,並加上了打印的函數用於比較 public void change(int c){ c=c*5; System.out.println(c); } public static void main(String[] args) { // TODO Auto-generated method stub int p=5; //先聲明一個變量p=5 shiyan c=new shiyan(); //創建對象c //利用c的成員函數改變p值,使p=p*5 c.change(p); //輸出的是理想值25 System.out.print(p); //奇怪輸出的是5 } }
輸出結果:25 5
分析:這就是按值傳遞的效果,因為此時傳入的不是p本身,只是p的值,傳遞的是p本身的是副本。
所以打印出的是(p副本的值)的改變結果25,而后一個打印出的是p的真身沒有改變過因此是5
//按引用傳遞
package yinyong; //先定義一個學生類 public class Student { //設計重載構造函數,為了后面的演示方便 public Student(){ } //用於取名的構造函數 public Student(String p){ name=p; } //用於改名的的函數,不過得改成別人的名字 public void changName(Student p){ this.name=p.name; } public String name; }
package yinyong; public class teacher { public static void main(String[] args) { // TODO Auto-generated method stub //創建a這個人給a學生取名李明 Student a=new Student("李明"); //創建b這個人給b學生取名趙明 Student b=new Student("趙明"); //創建c這個人,還未起名 Student c=new Student(); //分別輸出a,b兩個人的名字 System.out.println("a同學名字是"+a.name); System.out.println("b同學名字是"+b.name); //將c人的名字指向b,實質是將b的地址賦給c,這樣c,b同指一片內存區域 c=b; System.out.println("c同學名字是"+c.name); //果然c的名字變為了趙明 b.changName(a); //利用改名函數改變b的名字,將a對象傳入將a的名字賦給b System.out.println("b同學名字是"+b.name); //結果是a的名字李明 } }
輸出:a同學名字是李明
b同學名字是趙明
c同學名字是趙明
b同學名字是李明
分析: 由於是按引用調用所以,傳遞的時候時刻都是把對象的真身傳遞過去,並且可以改變真身的屬性和方法。傳遞時時候也把真身的地址傳了過去,這樣引用時就指向了同一片地址內存空間。