java面试一道令人怀疑人生的java面试题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013305783/article/details/82787726
   题目比较简单,写一个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();
        }
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u013305783/article/details/82787726
今日推荐