java基礎之Integer的封包、拆包和反射
阿新 • • 發佈:2019-01-25
先看一段程式碼例子:
執行的結果,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了。