Java值傳遞仍是引用傳遞?

回顧:java

在程序設計語言中,將參數傳遞分爲按值調用按引用調用。按值調用:表示方法接收的是調用者提供的。而按引用調用表示方法接收的是調用者提供的變量地址
一個方法能夠修改傳遞引用所對應的變量值,而不能修改傳遞值調用所對應的變量值。this

Java老是採用按值調用。方法獲得的是全部參數值的一個拷貝,特別的,方法不能修改傳遞給它的任何參數變量的內容。spa

方法參數共有兩種類型:設計

  • 基本數據類型
  • 對象引用

1. 基本數據類型爲參數

查看一下的代碼:code

public class ParamTest {
    public static void main(String[] args) {
        int price = 5;
        doubleValue(price);
        System.out.print(price);
    }

    public static void doubleValue(int x) {
        x = 2 * x;
    }
}

【輸出結果】: 5對象

能夠看到,這個方法執行以後,price的值並無變化。接下來,看一下doubleValue具體的執行過程爲:blog

  1. x被初始化爲price值的一個拷貝,即5
  2. x乘以2後等於10。可是price沒有變化,依然是5
  3. doubleValue執行完後,參數變量再也不使用

  

2. 對象引用爲參數

從上面的例子咱們已經知道一個方法不能修改一個基本數據類型的參數。而對象引用做爲參數就不一樣了。看下面的例子:get

class Student {

    private float score;

    public Student(float score) {
        this.score = score;
    }

    public void setScore(float score) {
        this.score = score;
    }

    public float getScore() {
        return score;
    }


}

public class ParamTest {
    public static void main(String[] args) {
        Student stu = new Student(80);
        raiseScore(stu);
        System.out.print(stu.getScore());
    }

    public static void raiseScore(Student s) {
        s.setScore(s.getScore() + 10);
    }
}

【運行結果】:程序設計

90.0class

能夠看出,Student實例s的內容改變了。

具體執行過程爲:

  1. s被賦予stu值的拷貝,這裏是一個對象的引用
  2. raiseScore方法應用於這個應用。s和stu指向同一對象,該對象的分數增長了10
  3. raiseScore方法結束後,s再也不使用,stu指向的那個對象分數增長了10

3. 對對象是值調用仍是引用傳遞?

首先編寫一個交換兩個學生的方法:

public static void swap(Student x, Student y) {
    Student temp = x;
    x = y;
    y = temp;
 } 

若是java對對象是採用的是引用傳遞,那個這個方法是能夠的。那麼x,y對象的分數是交換的。看下面的例子:

class Student {

    private float score;

    public Student(float score) {
        this.score = score;
    }

    public void setScore(float score) {
        this.score = score;
    }

    public float getScore() {
        return score;
    }
}

public class ParamTest {
    public static void main(String[] args) {
        Student a = new Student(0);
        Student b = new Student(100);

        System.out.println("交換前:");
        System.out.println("a的分數:" + a.getScore() + "--- b的分數:" + b.getScore());

        swap(a, b);

        System.out.println("交換後:");
        System.out.println("a的分數:" + a.getScore() + "--- b的分數:" + b.getScore());
    }

    public static void swap(Student x, Student y) {
        Student temp = x;
        x = y;
        y = temp;
    }
}

【運行結果】:

交換前:
a的分數:0.0--- b的分數:100.0
交換後:
a的分數:0.0--- b的分數:100.0

能夠看出,二者並無實現交換。說明引用傳遞的說法是不正確的。接下來一步一步看看swap調用的過程:

  1. 將對象a,b的拷貝分別賦值給x,y,此時a和x指向同一對象,b和y指向同一對象
  2. swap方法體完成x,y的的交換,此時a,b並無變化
  3. 方法執行完成,x和y再也不使用,a依舊指向new Student(0),b指向new Student(100)

首先,建立兩個對象:

而後,進入方法體,將對象a,b的拷貝分別賦值給x,y:

接着,交換x,y的值:

swap執行完成,x,y再也不使用,回到建立時狀態。

 

從這個過程當中能夠看出,Java對對象採用的不是引用調用,實際上,對象引用進行的是值傳遞。

總結一下java中方法參數的使用狀況:

  • 一個方法不能修改一個基本數據類型的參數(即數值型和布爾型)
  • 一個方法能夠改變一個對象參數的狀態
  • 一個方法不能讓對象參數引用一個新的對象
相關文章
相關標籤/搜索