先看一段代码例子:
public static void main(String[] args) {
Integer a1 = 1;
Integer b1 = 2;
Integer a2 = 1000;
Integer b2 = 2000;
Integer c1 = 3;
Integer c2 = 3;
Integer d1 = 300;
Integer d2 = 300;
System.out.println("a1="+a1+",b1="+b1);
System.out.println("a2="+a2+",b2="+b2);
System.out.println(c1==c2);
System.out.println(d1==d2);
swap1(a1,b1);
swap1(a2,b2);
System.out.println("a1="+a1+",b1="+b1);
System.out.println("a2="+a2+",b2="+b2);
}
private static void swap1(Integer num1, Integer num2){
Integer tem = num1;
num1 = num2;
num2 = tem;
}
运行的结果,
a1=1,b1=2
a2=1000,b2=2000
true
false
a1=1,b1=2
a2=1000,b2=2000
第一次a1,a2,b1,g2和第二次的值一样,这是因为Integer是值传递。
c1,c2,d1,d2的比较一个是true 一个是false,如果有看Integer源码的就知道了。
Integer内部有个IntegerCache内部类用来缓存-128到127。
Integer c1 = 1; 等价于 Integer c1=Integer.valueOf(1);
Integer.valueOf 内部处理
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看到,其中IntegerCache.low=-128,high = 127。当i的值在-128到127时是从缓存的常量池中取值的,
不在这个区间才是new出来的。所以c1==c2,d1!=d2。
那怎么让a1,b1,a2,b2的值调换呢?我们可以利用类的反射:
private static void swap2(Integer num1,Integer num2){
try {
Field field = Integer.class.getDeclaredField("value");//integer的构造方法默认变量时value
field.setAccessible(true);//允许改变
int tem = num1;
field.set(num1,num2);
field.set(num2,tem);
}catch (Exception e){
e.printStackTrace();
}
}
执行这个方法之后的结果:
a1=1,b1=2
a2=1000,b2=2000
a1=2,b1=2
a2=2000,b2=1000
可以看到 a2和b2的值成功的变了,而a1,b1的结果却是那样。
那是应为执行 field.set(num1,num2);时会把IntegerCache中的值给改变了。
我们只要修改成 field.set(num2, new Integer(tem));
这样执行结果就ok了。