现有Integer a=1,Integer b=2,互换a和b的值。
第一想法
public static void main(String[] args) {
Integer a=1,b=2;
System.out.println("before :a="+a+","+"b="+b);
swap(a,b);
System.out.println("after :a="+a+","+"b="+b);
}
private static void swap(Integer a, Integer b) {
Integer temp = a;
a = b;
b = temp;
}
结果a=1 b=2,失败。原因是在java中,封装变量Integer传递是副本,不是地址。所以值没有改变。
再探究,使用反射的方法。
public static void main(String[] args) {
//自动装箱
Integer a = 1, b = 2;
//相当于 Integer a = Integer.value(1)
System.out.println("before :a="+a+","+"b="+b);
try {
swap(a,b);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("after :a="+a+","+"b="+b);
}
/**
* @param a
* @param b
*/
private static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
Field field = Integer.class.getDeclaredField("value");
field.setAccessible(true);///可以访问私有成员变量
Integer temp = a.intValue(); //错误
//Integer temp = new Integer(a); 正确
System.out.println(temp);
field.set(a,b);
field.set(b,temp);
System.out.println(temp);
}
结果:a=2,b=2,原因:通过反射修改a的引用的时候,temp也同时被修改了,故用temp修改b的时候,b还是为2.
经过查究,发现需要new 一个新的Integer来接受a的值。这样修改a的时候,temp不会被修改,最终结果就是a=2,b=1.