1. 程式人生 > >Java 如何用方法交換兩個變數的值

Java 如何用方法交換兩個變數的值

在學習C++的時候,我們需要學習如何用指標和方法來交換兩個變數的值,比如swap(int*, int*)。而當我學習Java的時候,因為沒有指標,所以我們需要另求他法。這引起了我下面的思考:

(1)方法不能修改基本型別的引數

例如swap(int a, int b); 無論方法內如何修改a和b的值,原來的a和b都不會改變。
public class SwapDemo01 {

	public static void main(String[] args) {
		/**
		 * 方法不能改變基本型別的引數
		 */
		int a = 1;
		int b = 2;
		swap(a, b);
		System.out.println("在main()方法內:");
		System.out.println("a: " + a);
		System.out.println("b: " + b);
	}

	public static void swap(int a, int b) {
		a ^= b;
		b ^= a;
		a ^= b;
		System.out.println("在swap()方法內:");
		System.out.println("a: " + a);
		System.out.println("b: " + b);
	}
結果如下: 在swap()方法內:
a: 2
b: 1
在main()方法內:
a: 1
b: 2

(2)方法可以修改物件引數的狀態

當物件作為引數傳遞給方法時,在方法內部,可以用該物件的公共方法來修改物件的狀態(或內容)。
public class SwapDemo02 {

	public static void main(String[] args) {
		/**
		 * 方法可以改變物件引數的狀態
		 */
		StringBuffer str1 = new StringBuffer("Hello");
		StringBuffer str2 = new StringBuffer("World");
		swap(str1, str2);
		System.out.println("在main()方法內:");
		System.out.println("str1: " + str1.toString());
		System.out.println("str2: " + str2.toString());
	}

	public static void swap(StringBuffer str1, StringBuffer str2) {
		StringBuffer temp = new StringBuffer(str1.toString());
		str1.delete(0, str1.length());
		str1.append(str2.toString());
		str2.delete(0, str2.length());
		str2.append(temp.toString());
		System.out.println("在swap()方法內:");
		System.out.println("str1: " + str1.toString());
		System.out.println("str2: " + str2.toString());
	}
結果如下: 在swap()方法內:
str1: World
str2: Hello
在main()方法內:
str1: World
str2: Hello
可以看到,swap方法已經成功交換了兩個字串的內容。

(3)方法不能使一個物件引數指向一個新的物件

在上面的第二個方法中,我們通過公共方法來修改物件,不是挺麻煩的嗎?為什麼不直接交換兩個物件呢?或者說讓物件互相指向對方,不行嗎?下面的測試告訴你,確實不行。
public class SwapDemo03 {

	public static void main(String[] args) {
		/**
		 * 方法不能使一個物件引數指向一個新的物件
		 */
		String str1="Hello";
		String str2="World";
		swap(str1, str2);
		System.out.println("在main()方法內:");
		System.out.println("str1: " + str1);
		System.out.println("str2: " + str2);
	}
	
	public static void swap(String str1, String str2) {
		String temp = str1;
		str1 = str2;
		str2 = temp;
		System.out.println("在swap()方法內:");
		System.out.println("str1: " + str1);
		System.out.println("str2: " + str2);
	}

}
結果如下: 在swap()方法內:
str1: World
str2: Hello
在main()方法內:
str1: Hello
str2: World 可以看到,在swap方法內,兩個String指向的字串已經改變了,而main方法中兩個字串並沒有改變。

(4)總結規律

通過上面的實驗,我們可以知道對於基本型別,引數傳遞的是變數的值,方法無法改變原變數的值。對於物件,引數傳遞的是物件的地址,我們可以根據物件的地址改變物件的狀態,但是不能改變原物件的地址。從記憶體管理的角度來講,物件的名稱和地址是儲存在棧內的,物件的內容狀態是儲存在堆中的,棧內的地址指向堆內的物件狀態。當物件作為引數時,相當於把物件的地址複製一份給方法,方法可以根據地址改變物件的狀態,也可以修改引數傳進來的這個地址,但是不能修改物件本身儲存在棧內的地址。 ps.其實可以通過“歪門邪道”改變基本型別的值:將兩個變數儲存在陣列內,將陣列傳遞給方法。這樣在方法內交換陣列內的值,就真的交換了兩個變數的值了。這種方法有點類似於上面第二種方法。