1. 程式人生 > >java面試一道令人懷疑人生的java面試題

java面試一道令人懷疑人生的java面試題

   題目比較簡單,寫一個swap方法,交換兩個Integer的值。

方法一

使用中間變數直接交換

private static void  swap(Integer num1,Integer num2){
        Integer tmp = num1;
        num1 = num2;
        num2 = tmp;
 }
   當然,如果僅僅按照以上方結果是不能交換的值,因為num1與num2是區域性變數,方法結束後值還是沒有變,除非有相應的返回值來解決。

方法二

使用反射

private static void  swap(Integer num1,Integer num2){
//        Integer tmp = num1;
//        num1 = num2;
//        num2 = tmp;
        try {
            Field field = Integer.class.getDeclaredField("value");
            field.setAccessible(true);
            int tmp = num1;//拆箱
            field.set(num1,num2);
            field.set(num2,tmp);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   如上所示,但是結果還是不是我們預期的,結果如下

在這裡插入圖片描述

   是什麼原因導致的呢?開啟Integer的原始碼如下:

	public static Integer valueOf(int i) {
	        if (i >= IntegerCache.low && i <= IntegerCache.high)
	            return IntegerCache.cache[i + (-IntegerCache.low)];
	        return new Integer(i);
	  }
   我們發現,Interger取值時是首先判斷IntegerCache,而IntegerCache值的範圍是[-128]-[127],當我們 field.set(num1,num2)時,IntegerCache中對應num1的位置是IntegerCache[129],即IntegerCache[129]的值被改為2,而執行到 field.set(num2,tmp)時,會對tmp進行裝箱操作,但是tmp的值同樣在[-128]-[127],即會去取IntegerCache[129]的值,而此時IntegerCache[129]的值為2,所以field.set(num2,tmp)後num2的值還是2.
   要解決上面出現的問題目前有兩種方法:方法一 在使用tmp是重新new一個新物件,即field.set(num2,new Integer(tmp))。
private static void  swap(Integer num1,Integer num2){
//        Integer tmp = num1;
//        num1 = num2;
//        num2 = tmp;
        try {
            Field field = Integer.class.getDeclaredField("value");
            field.setAccessible(true);
            int tmp = num1;//拆箱
            field.set(num1,num2);
            field.set(num2,new Integer(tmp));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在這裡插入圖片描述

   方法二、直接將值作為一個int型別,不進行拆裝箱操作即field.setInt(num2,tmp);

private static void  swap(Integer num1,Integer num2){
//        Integer tmp = num1;
//        num1 = num2;
//        num2 = tmp;
        try {
            Field field = Integer.class.getDeclaredField("value");
            field.setAccessible(true);
            int tmp = num1;//拆箱
            field.set(num1,num2);
            field.setInt(num2,tmp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在這裡插入圖片描述