1. 程式人生 > >java基礎之Integer的封包、拆包和反射

java基礎之Integer的封包、拆包和反射

先看一段程式碼例子:

 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了。