函數傳參
1.傳參方式
函數傳遞參數的方式有兩種
按值傳參,函數接收的是調用者提供的值
按引用傳參,函數接收到的是調用者提供的變量地址
函數傳參流程
那么java是按什么方式傳參呢?答案是采用按值傳參,函數的形參得到的是實參值的一份拷貝。
2.傳遞的參數為基本數據類型
1 public class Test { 2 public static void doubleValue(int num) { 3 num = num * 2; 4 } 5 6 public static void main(String[] args) { 7 int x = 1; 8 doubleValue(x); 9 System.out.println(x); //1 10 } 11 }
執行過程
(1)調用函數doubleValue(x)時,num被初始化為x值的一份拷貝,即num=1;
(2)在函數體內,num乘以2以后等於2,但是x還是1;
(3)函數執行結束后,變量num不再使用。
3.傳遞的參數為引用類型
1 package ja.see.models; 2 3 class Employee { 4 private double salary; 5 6 public Employee(double salary) { 7 this.salary = salary; 8 } 9 10 public double getSalary() { 11 return salary; 12 } 13 14 public void setSalary(double salary) { 15 this.salary = salary; 16 } 17 18 public void doubleSalary(double salary) { 19 this.salary = 2 * salary; 20 } 21 } 22 23 public class Test { 24 public static void increaseSalary(Employee e) { 25 e.doubleSalary(e.getSalary()); 26 } 27 28 public static void main(String[] args) { 29 Employee e1 = new Employee(3000.00); 30 System.out.println("After method: " + e1.getSalary()); 31 increaseSalary(e1); 32 System.out.println("After method: " + e1.getSalary()); 33 } 34 }
執行過程
(1)函數increaseSalary執行時,e被初始化為e1值的拷貝即Employee對象引用的一份拷貝,e與e1引用同一個對象
(2)在函數體內,操作這個對象的引用,e與e1同時引用的對象薪水乘以2
(3)函數執行結束后,變量e不再使用,變量e1繼續引用那個薪水被修改為2倍的Employee對象實例
4.舉例反證
上面的這個栗子,如果建立在java函數傳參是引用傳參的觀點上也是成立的,所以下面我們來舉例證明java函數傳參是按值傳參。
package com.java.se; class Employee { private String name; public Employee(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Test { public static void sayName(Employee e) { e = new Employee("tom"); } public static void main(String[] args) { Employee e1 = new Employee("lily"); System.out.println("Before method: " + e1.getName()); //lily sayName(e1); System.out.println("After method: " + e1.getName()); //lily } }
如果java函數是按引用傳參,那么After Method后e1.getName()應該是tom而不是lily;
5.說明
1)在向函數傳遞對象類型的值時,是將實參對象(e1)的內存地址復制給函數的形參(e),即它們引用的是同一個對象;
2)當函數內部的形參(e)操作這個對象時,外部的實參對象(e1)也會有所體現;
3)但是當將一個新的Employee對象賦值給變量e,同時將其name屬性設置為"tom";
如果e1是按引用傳遞的,那么接下來訪問e1.name時應該是"tom",但是結果仍然時"lily";
4)這說明函數內部參數(e)值的修改並不能影響外部實參(e1)的引用;
5)當函數內部參數值(e)修改時,這個參數(e)引用的就是一個局部變量對象了,不再是原先的對象,
6)當函數執行結束時,該局部變量對象會被銷毀。
6.總結
(1)一個函數不能修改一個基本數據類型的實參(數值型和布爾型)
(2)一個函數可以改變一個對象實參的狀態(但是不能改變一個對象實參的引用)
(3)一個函數不能讓一個對象實參去引用一個新的對象
參考資料:《JAVA核心技術》