学过C语言的人都知道,在C中交换两个变量可以通过指针的方式实现:
void swap(int *a, int *b)
{
int temp;
temp = a;
a = b;
b = temp;
}
C++里面可以使用指针也可以使用引用来实现:
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中不能直接操作指针变量,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中函数或者叫方法的入参都是通过值拷贝的方式进行传递:
通过反射可以实现简单的swap。