Java 方法引數
Java 程式設計語言總是採用按值呼叫。也就是說,方法得到的是所有引數值的一個拷貝,特別是,方法不能修改傳遞給它的任何引數的內容。
例如,下面的呼叫:
double percent = 10;
harry.raiseSalary(percent);
在方法呼叫之後,percent的值還是10。程式碼如下:
public class ParamTest { public static void main(String [] args){ System.out.println("Testing tripleValue:"); double percent = 10; System.out.println("Before:percent=" + percent); tripleValue(percent); System.out.println("After:percent=" + percent); } public static void tripleValue(double x){ x = 3*x; System.out.println("End of method: x="+x); } }
執行結果:
可以看到,無論怎樣,呼叫這個方法之後,percent的值還是10。看一下具體的執行過程:
1)x被初始化為percent值的一個拷貝(也就是10)。
2)x被乘以3後等於30。但是percent仍然是10。
3)這個方法結束之後,引數變數x不再使用。
方法引數共有兩種型別:
1、基本資料型別(數字、布林值)。
2、物件引用。
我已經知道,一個方法不可能修改一個基本資料型別的引數。而物件引用作為引數就不一樣了,可以利用下面這個方法實現將一個僱員是的薪金提高兩倍的操作:
具體程式碼:public static void tripleSalary(Employee x) { x.raiseSalary(200); }
執行結果:public class ParamTest { public static void main(String [] args){ System.out.println("\nTesting tripleSalary:"); Employee harry = new Employee("Harry",50000); System.out.println("Before: salary=" + harry.getSalary()); tripleSalary(harry); System.out.println("After: salary=" + harry.getSalary()); } public static void tripleSalary(Employee x){ x.raiseSalary(200); System.out.println("End of method: salary=" + x.getSalary()); } } public class Employee { private String name; private double salary; public Employee(String n,double s){ name = n; salary = s; } public String getName() { return name; } public double getSalary() { return salary; } public void raiseSalary(double byPercent){ double raise = salary*byPercent/100; salary+=raise; } }
具體執行過程:
1、x被初始化為harry值的拷貝,這裡是個物件的引用。
2、raiseSalary方法應用於這個物件引用。x和harry同時引用的那個Employee物件的薪金提高了200%。
3、方法結束後,引數變數x不再使用。當然,物件變數harry繼續引用那個薪金增至3倍的僱員物件。
由上可知,實現一個改變物件引數狀態的方法並不是一件難事。因為,方法得到的是物件引用的拷貝,物件引用及其他的拷貝同時引用統一個物件。
很多程式設計語言提供了兩種引數傳遞的方式:值呼叫和引用呼叫。有些人認為Java程式設計語言對物件採用的是引用呼叫,實際上,這種理解是不對的。由於這種理解有一定的普遍性,所以下面給出一個範反例來詳細闡述。
首先,編寫一個交換兩個僱員物件的方法:
public static void swap(Employee x,Employee y){
Employee temp=x;
x = y;
y = temp;
}
如果Java設計語言對物件採用的是引用呼叫,這個方法就應該能夠實現交換資料的效果:
Emloyee a = new Emloyee("Alice",...);
Emloyee a = new Emloyee("Bob",...);
swap(a,b);
但是,方法並沒有改變儲存在變數a和b的物件引用。swap方法的引數x和y被初始化為兩個物件引用的拷貝,這個方法交換的是這兩個拷貝。具體程式碼:
public class Ey {
public static void swap(Employee x,Employee y){
Employee temp = x;
x = y;
y = temp;
System.out.println("End of method: x="+x.getName());
System.out.println("End of method: y="+y.getName());
}
public static void main(String [] args){
Employee a = new Employee("Alice",200);
Employee b = new Employee("Bob",400);
System.out.println("\nTesting swap:");
System.out.println("Before:a=" + a.getName());
System.out.println("Before:b=" + b.getName());
swap(a,b);
System.out.println("After:a=" + a.getName());
System.out.println("After:b=" + b.getName());
}
}
public class Employee {
private String name;
private double salary;
public Employee(String n,double s){
name = n;
salary = s;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public void raiseSalary(double byPercent){
double raise = salary*byPercent/100;
salary+=raise;
}
}
執行結果:
最終,白費力氣。在方法結束時引數變數x和y被丟棄了。原來的變數a和b仍然引用這個方法呼叫之前所引用的物件
這個過程說明:Java程式設計語言對物件採用的不是引用呼叫,實際上,物件引用進行的是值傳遞。
下面總結一下Java程式設計語言中方法引數的使用情況:
1、一個方法不能修改一個基本資料型別的引數(即數值型和布林型)。
2、一個方法可以改變一個物件引數的狀態。
3、一個方法不能讓物件引數引用一個新的物件。