日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

深入理解Java中方法的參數(shù)傳遞機制

 

形參和實參

我們知道,在JAVA中定義方法時,是可以定義參數(shù)的,比如:

public static void main(String[] args){
 
}

這里的args就是一個字符串?dāng)?shù)組類型的參數(shù)。

在程序設(shè)計語言中,參數(shù)有形式參數(shù)和實際參數(shù)之分,先來看下它們的定義:

形式參數(shù):是在定義函數(shù)名和函數(shù)體的時候使用的參數(shù),目的是用來接收調(diào)用該函數(shù)時傳入的參數(shù),簡稱“形參”。

實際參數(shù):在主調(diào)函數(shù)中調(diào)用一個函數(shù)時,函數(shù)名后面括號中的參數(shù)稱為“實際參數(shù)”,簡稱“實參”。

舉個栗子:

public class ParamTest {
 public static void main(String[] args) {
 ParamTest pt = new ParamTest();
 // 實際參數(shù)為“張三”
 pt.sout("張三");
 }
?
 public void sout(String name) {
 // 形式參數(shù)為 name
 System.out.print(name);
 } 
}

上面例子中,ParamTest類中定義了一個sout方法,該方法有個String類型的參數(shù)name,該參數(shù)即為形參。在main方法中,調(diào)用了sout方法,傳入了一個參數(shù)“張三”,該參數(shù)即為實參。

那么,實參值是如何傳入方法的呢?這是由方法的參數(shù)傳遞機制來控制的。

值傳遞和引用傳遞

參數(shù)傳遞機制有兩種:值傳遞和引用傳遞。我們先來看下程序語言中是如何定義和區(qū)分值傳遞和引用傳遞的:

值傳遞:是指在調(diào)用函數(shù)時將實際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣在函數(shù)中如果對參數(shù)進行修改,將不會影響到實際參數(shù)。

引用傳遞:是指在調(diào)用函數(shù)時將實際參數(shù)的地址傳遞到函數(shù)中,那么在函數(shù)中對參數(shù)所進行的修改,將影響到實際參數(shù)。

那么,在我們大Java中,到底是值傳遞還是引用傳遞呢?

Java中是值傳遞還是引用傳遞?

有了上面的概念,我們就可以一起來探究一下,Java中方法參數(shù)到底是值傳遞還是引用傳遞了。

先看如下代碼:

public class ParamPass1 {
 public static void main(String[] args) {
 ParamPass1 p = new ParamPass1();
 int i = 10;
 System.out.println("pass方法調(diào)用前,i的值為=" + i);
 p.pass(i);
 System.out.println("pass方法調(diào)用后,i的值為=" + i);
 }
?
 public void pass(int i) {
 i *= 3;
 System.out.println("pass方法中,i的值為=" + i);
 }
}

上面代碼中,我們在類中定義了一個pass方法,方法內(nèi)部將傳入的參數(shù)i的值增加至3倍,然后分別在pass方法和main方法中打印參數(shù)的值,輸出結(jié)果如下:

pass方法執(zhí)行前,i的值為=10
pass方法中,i的值為=30
pass方法執(zhí)行后,i的值為=10

從上面運行結(jié)果來看,pass方法中,i的值是30,pass方法執(zhí)行結(jié)束后,變量i的值依然是10。

可以看出,main方法里的變量i,并不是pass方法里的i,pass方法內(nèi)部對i的值的修改并沒有改變實際參數(shù)i的值,改變的只是pass方法中i的值(pass方法中,i=30),因為pass方法中的i只是main方法中變量i的復(fù)制品。

因此同學(xué)們很容易得出結(jié)論:Java中,一個方法不可能修改一個基本數(shù)據(jù)類型的參數(shù) ,所以是值傳遞。

然而,結(jié)論下的還太早,因為方法參數(shù)共有兩種類型:

  1. 基本數(shù)據(jù)類型
  2. 引用數(shù)據(jù)類型

前面看到的只是基本數(shù)據(jù)類型的參數(shù),那對于引用類型的參數(shù),又是怎么樣的呢?看如下代碼:

public class ParamPass2 {
 public static void main(String[] args) {
 ParamPass2 p = new ParamPass2();
?
 User user = new User();
 user.setName("張三");
 user.setAge(18);
?
 System.out.println("pass方法調(diào)用前,user=" + user.toString());
 p.pass(user);
 System.out.println("pass方法調(diào)用后,user=" + user.toString());
 }
?
 public void pass(User user) {
 user.setName("李四");
 System.out.println("pass方法中,user = " + user.toString());
 }
}
?
class User {
 /**
 * 姓名
 */
 private String name;
 
 /**
 * 年齡
 */
 private int age;
?
 public String getName() {
 return name;
 }
?
 public void setName(String name) {
 this.name = name;
 }
?
 public int getAge() {
 return age;
 }
?
 public void setAge(int age) {
 this.age = age;
 }
?
 @Override
 public String toString() {
 return "User{" +
 "name='" + name + ''' +
 ", age=" + age +
 '}';
 }
}

上面代碼中,定義了一個User類,在main方法中,new了一個新的User對象user,然后給user對象的成員變量賦值,pass方法中,修改了傳入的user對象的屬性。

運行main方法,結(jié)果如下:

pass方法調(diào)用前,user= User{name='張三', age=18}
pass方法中,user = User{name='李四', age=18}
pass方法調(diào)用后,user= User{name='李四', age=18}

經(jīng)過pass方法執(zhí)行后,實參的值竟然被改變了!!!那按照上面的引用傳遞的定義,實際參數(shù)的值被改變了,這不就是引用傳遞了么?

有同學(xué)可能會說:難道在Java的方法中,在傳遞基本數(shù)據(jù)類型的時候是值傳遞,在傳遞引用數(shù)據(jù)類型的時候是引用傳遞?

其實不然,Java中傳遞引用數(shù)據(jù)類型的時候也是值傳遞。

為什么呢?

先給大家說一下概念中的重點:

值傳遞,是指在調(diào)用函數(shù)時將實際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣在函數(shù)中如果對參數(shù)進行修改,將不會影響到實際參數(shù)。

引用傳遞,是指在調(diào)用函數(shù)時將實際參數(shù)的地址直接傳遞到函數(shù)中,那么在函數(shù)中對參數(shù)所進行的修改,將影響到實際參數(shù)。

總結(jié)下兩者的區(qū)別:

值傳遞引用傳遞根本區(qū)別會創(chuàng)建副本不會創(chuàng)建副本所以函數(shù)中無法改變原始對象函數(shù)中可以改變原始對象

敲黑板:復(fù)制的是參數(shù)的引用(地址值),并不是引用指向的存在于堆內(nèi)存中的實際對象。

main方法中的user是一個引用(也就是一個指針),它保存了User對象的地址值,當(dāng)把user的值賦給pass方法的user形參后,即讓pass方法的user形參也保存了這個地址值,即也會引用到堆內(nèi)存中的User對象。

上面代碼中,之所以產(chǎn)生引用傳遞的錯覺,是因為參數(shù)保存的是實際對象的地址值,你改變的只是地址值指向的堆內(nèi)存中的實際對象,并沒有真正改變參數(shù),參數(shù)的地址值沒有變。

下面結(jié)合生活中的場景,再來深入理解一下值傳遞和引用傳遞。

你有一把鑰匙,當(dāng)你的朋友想要去你家的時候,如果你直接把你的鑰匙給他了,這就是引用傳遞。這種情況下,如果他對這把鑰匙做了什么事情,比如他在鑰匙上刻下了自己名字,那么這把鑰匙還給你的時候,你自己的鑰匙上也會多出他刻的名字。

你有一把鑰匙,當(dāng)你的朋友想要去你家的時候,你復(fù)刻了一把新鑰匙給他,自己的還在自己手里,這就是值傳遞。這種情況下,他對這把鑰匙做什么都不會影響你手里的這把鑰匙。

但是,不管上面哪種情況,你的朋友拿著你給他的鑰匙,進到你的家里,把你家的電視砸了。那你說你會不會受到影響?

我們在pass方法中,改變user對象的name屬性的值的時候,不就是在“砸電視”么。你改變的不是那把鑰匙(地址值),而是鑰匙打開的房子(地址值對應(yīng)的實際對象)。

那我們?nèi)绾握嬲母淖儏?shù)呢,看如下代碼:

public class ParamPass3 {
 public static void main(String[] args) {
 ParamPass3 p = new ParamPass3();
?
 User user = new User();
 user.setName("張三");
 user.setAge(18);
?
 System.out.println("pass方法調(diào)用前,user= " + user.toString());
 p.pass(user);
 System.out.println("pass方法調(diào)用后,user= " + user.toString());
 }
?
 public void pass(User user) {
 user = new User();
 user.setName("李四");
 user.setAge(20);
 System.out.println("pass方法中,user = " + user.toString());
 }
}
?
class User {
 /**
 * 姓名
 */
 private String name;
 /**
 * 年齡
 */
 private int age;
?
 public String getName() {
 return name;
 }
?
 public void setName(String name) {
 this.name = name;
 }
?
 public int getAge() {
 return age;
 }
?
 public void setAge(int age) {
 this.age = age;
 }
?
 @Override
 public String toString() {
 return "User{" +
 "name='" + name + ''' +
 ", age=" + age +
 '}';
 }
}

在這段代碼中,pass方法中,我們真正的改變了user參數(shù),因為它指向了一個新的地址(user = new User()),即參數(shù)的地址值改變了。運行結(jié)果如下:

pass方法調(diào)用前,user= User{name='張三', age=18}
pass方法中,user = User{name='李四', age=20}
pass方法調(diào)用后,user= User{name='張三', age=18}

從結(jié)果看出,對參數(shù)進行了修改,沒有影響到實際參數(shù)。

所以說,Java中其實還是值傳遞的,只不過對于引用類型參數(shù),值的內(nèi)容是對象的引用。

分享到:
標(biāo)簽:參數(shù) Java
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定