1. 程式人生 > >Java 方法引數

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、一個方法不能讓物件引數引用一個新的物件。