美文网首页
剖析一道不简单的面试题

剖析一道不简单的面试题

作者: 康俊1024 | 来源:发表于2019-04-21 22:55 被阅读0次

    问题

    如何实现两个Integer的引用对象传给一个swap方法在方法内部进行交换?

    第一版(直接交换)

      public static void main(String[] args) throws Exception {
            Integer a = 1,b = 2;
            System.out.println("before: a="+ a +",b="+b);   //
            swap(a,b);
            System.out.println("after: a="+ a +",b="+b);
        }
    
        private static void swap(Integer a, Integer b) throws Exception {
            Integer temp = a;
            a = b;
            b = temp;
        }
      //结果
      before: a=1,b=2
      after: a=1,b=2
    

    失败原因

    参数传递:值传递和引用传递
    Java中变量:基本类型和引用类型
    swap接收修改的是值的副本

    查看字节码

    字节码文件.png
    Integer a = 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);
        }
        public Integer(int value) {
            this.value = value;
        }
        private final int value;
    

    创建的值会保存在成员变量value中

    第二版(通过反射机制修改value的值)

        public static void main(String[] args) throws Exception {
            Integer a = 1,b = 2;
            System.out.println("before: a="+ a +",b="+b);
            swap(a,b);
            System.out.println("after: a="+ a +",b="+b);
        }
        private static void swap(Integer a, Integer b) throws Exception {
            Field field = Integer.class.getDeclaredField("value");//获取私有的成员变量
            field.setAccessible(true);//授权访问这些私有的变量并进行修改
            int a1 = a.intValue(); //
            field.set(b,a1);           //交换成功 b=1
            field.set(a,b.intValue());// 交换失败 a=1  Integer.valueOf(b.intValue()).intValue()
        }
       //结果
       before: a=1,b=2
      after: a=1,b=1
    

    失败原因

    在-128 - 127之间默认使用同一块内存地址,所以a=b=1

    private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    
            private IntegerCache() {}
    }
    

    第三版(创建一个新的对象)

         public static void main(String[] args) throws Exception {
            Integer a = 1,b = 2;  //Integer a = Integer.valueOf(1);
            System.out.println("before: a="+ a +",b="+b);
            swap(a,b);
            System.out.println("after: a="+ a +",b="+b);
        }
    
        private static void swap(Integer a, Integer b) throws Exception {
            Field field = Integer.class.getDeclaredField("value");//获取私有的成员变量
            field.setAccessible(true);//授权访问这些私有的变量并进行修改
           // int a1 = a.intValue();
            Integer a1 = new Integer(a.intValue());
            field.set(a,b.intValue());// 交换失败 a=1   Integer.valueOf(b.intValue()).intValue()
            field.set(b,a1);           //交换成功 b=1
        }
    

    考察的知识点

    • -128到127之间有缓存的概念
    • 自动装箱和拆箱
    • 反射,通过反射去修改private final变量

    相关文章

      网友评论

          本文标题:剖析一道不简单的面试题

          本文链接:https://www.haomeiwen.com/subject/dcrsgqtx.html