1.當(dāng)我們調(diào)用一個(gè)有參函數(shù)的時(shí)候,會(huì)把實(shí)際參數(shù)傳遞給形式參數(shù)
2.這樣的傳遞分成兩種:
值傳遞(pass by value)是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣在函數(shù)中如果對(duì)參數(shù)進(jìn)行修改,將不會(huì)影響到實(shí)際參數(shù)。
引用傳遞(pass by reference)是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)的地址直接傳遞到函數(shù)中,那么在函數(shù)中對(duì)參數(shù)所進(jìn)行的修改,將影響到實(shí)際參數(shù)。
所以,值傳遞會(huì)創(chuàng)建副本,函數(shù)中無(wú)法改變?cè)紝?duì)象
引用傳遞不會(huì)創(chuàng)建副本,函數(shù)里面可以改變?cè)紝?duì)象
3.通過(guò)三種場(chǎng)景下的實(shí)驗(yàn):
1.參數(shù)類(lèi)型為基本數(shù)據(jù)類(lèi)型
2.參數(shù)類(lèi)型為引用數(shù)據(jù)類(lèi)型,但改變的是對(duì)象的屬性,“砸電視”的舉例
3.參數(shù)類(lèi)型為引用類(lèi)型時(shí),實(shí)際改變的是對(duì)象本身。
我們得出結(jié)論:Java是值傳遞的,只不過(guò)對(duì)于參數(shù)是引用類(lèi)型時(shí),值的內(nèi)容是對(duì)象的引用。
4.無(wú)論是值傳遞還是引用傳遞,其實(shí)都是一種求值策略,在求值策略中,還有一種叫做按共享傳遞,按共享傳遞,是指在調(diào)用函數(shù)時(shí),傳遞給函數(shù)的是實(shí)參的地址的拷貝(如果實(shí)參在棧中,則直接拷貝該值)。在函數(shù)內(nèi)部對(duì)參數(shù)進(jìn)行操作時(shí),需要先拷貝的地址尋找到具體的值,再進(jìn)行操作。如果該值在棧中,那么因?yàn)槭侵苯涌截惖闹担院瘮?shù)內(nèi)部對(duì)參數(shù)進(jìn)行操作不會(huì)對(duì)外部變量產(chǎn)生影響。如果原來(lái)拷貝的是原值在堆中的地址,那么需要先根據(jù)該地址找到堆中對(duì)應(yīng)的位置,再進(jìn)行操作。因?yàn)閭鬟f的是地址的拷貝所以函數(shù)內(nèi)對(duì)值的操作對(duì)外部變量是可見(jiàn)的。
public class ArgsDemo {
public static void main(String[] args) {
int a=10;
int b=20;
change(a,b);
System.out.println("a="+a+",b="+b);
int[] arr={1,2,3,4,5};
System.out.println("change方法調(diào)用之前的"+arr);
change(arr);
System.out.println(arr[2]);
System.out.println("change方法調(diào)用之后的"+arr);//16行與19行相等的結(jié)果證明了我們的Java是值傳遞,而18行的改變我們類(lèi)比作"砸電視"
ArgsDemo ad = new ArgsDemo();
User user = new User();
user.setName("關(guān)羽");
System.out.println("調(diào)用前的user:"+user);
ad.pass(user);//非靜態(tài)方法
System.out.println(user.getName()+"");
System.out.println("調(diào)用后的user:"+user);
String name ="張飛";
ad.pass2(name);
System.out.println(name);//既然都是值傳遞,為什么傳遞String類(lèi)型和傳遞User類(lèi)型不一樣,傳遞String類(lèi)型時(shí)可以很
//清楚地看到不改變?cè)瓍?shù)的值,
//這是因?yàn)椋旅娴腟tr = "呂蒙"實(shí)際是 String str = new String("呂蒙");也更改了地址值。
}
public static void change(int a,int b){
a=b;
b=a+b;
System.out.println("a="+a+",b="+b);
}
public static void change(int[] arr){
for (int i = 0; i <arr.length ; i++) {
if(i%2==0){
arr[i]*=2;
}
}
}
public void pass(User user){
//user = new User();//仔細(xì)體味值傳遞和引用傳遞的概念,說(shuō)的都是對(duì)參數(shù)操作,是參數(shù)改不改變
user.setName("呂布");//砸電視
System.out.println("pass方法里的user:"+user);
System.out.println(user.getName()+"");
}
public void pass2(String str){
str = "呂蒙";
System.out.println(str);
}
}