C/C++中的swap
void swap(int *a, int *b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void swap1(int *a, int *b)
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void swap2(int &a, int &b){
int temp;
temp = a;
a = b;
b = temp;
}
運行結果
Java中的swap
Java中不能直接操作指針變量,int、double、float等基本類型函數傳參的時候都是值傳遞,也就是傳入函數的只是原來變量的一個副本,所以在函數中交換是副本,並達不到交換的目的。
對象的傳遞是引用傳遞(和C++中的引用不同),也是一個副本,在函數中修改值也達不到交換目的。
在內存中是這個樣子的:
實際上交換了引用副本的值。
所以真的沒有辦法實現了嗎?當然不是,我使用反射機制實現了對Integer類的swap,其他的對象也類似,但是真的沒有必要這麼做,盡力去實現也沒有實際意義,抓緊時間去學習有意義的東西吧。
代碼:
import java.lang.reflect.Field;
public class SwapTest {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
System.out.println(a + " " + b);
swap(a, b);
System.out.println(a + " " + b);
}
public static void swap(Integer a, Integer b) {
if (a == null || b == null) {
return;
}
//獲得a的class對象
Class<Integer> integerClass = (Class<Integer>) a.getClass();
try {
//獲得value屬性
Field value=integerClass.getDeclaredField("value");
//設置權限爲可訪問
value.setAccessible(true);
//交換
int temp=a;
value.setInt(a,b);
value.setInt(b,temp);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
// public static void swap(Integer a, Integer b) {
// Integer temp;
// temp = a;
// a = b;
// b = temp;
// }
// public static void swap(int a, int b) {
// int temp;
// temp = a;
// a = b;
// b = temp;
// }
}
總結
C/C++中swap是通過傳遞變量地址(指針或引用)來交換變量地址中的值。Java對程序員屏蔽了變量地址的概念,爲的是減少指針誤用。
在Java中函數或者叫方法的入參都是通過值拷貝的方式進行傳遞:
- 原始類型(char,int,double等)都是通過直接拷貝變量值傳參;
- 對象類型都是通過引用拷貝(跟C++中引用不同)傳參,通過該引用能夠更改其指向的對象內部值,但是更改該引用值,僅對函數內部可見,函數外部的實參依然沒有改變;
通過反射可以實現簡單的swap。