• Integer判等的陷阱:你知道Integer内部高速缓冲区IntegerCache吗?


    https://blog.csdn.net/magician_Code/article/details/51469101

    我们先来看看下面代码的运行情况:

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        Integer integer1;
        Integer integer2;
    
        integer1 = new Integer(10);
        integer2 = new Integer(10);
        //第一次比较
        System.out.println("第一次比较:"+(integer1==integer2));
    
        //第二次比较
        System.out.println("第二次比较:"+(integer1==10));
    
        integer1 = 127;
        integer2 = 127;
        //第三次比较
        System.out.println("第三次比较:"+(integer1==integer2));
    
        integer1 = 128;
        integer2 = 128;
        //第四次比较
        System.out.println("第四次比较:"+(integer1==integer2));
    }

    运行程序,结果如下:

    你看出了运行结果了吗?

    第一次和第二次比较就无可厚非了,第一次是直接把两个不同的对象比较,当然是false;第二次比较时,是把Integer对象和int型10进行比较,根据自动装箱、拆箱机制,这时候的比较就等价于10==10,所以是true。那么后面两个为什么会出现两种不同的结果呢?

    首先我们先来看看Integer的两种定义方式:

    Integer integer1 = new Integer(10);
    Integer integer2 = 10;

    第一种是我们常见的创建一个对象的方法,那么第二个方法呢?根据Java的自动装箱、拆箱机制,这时在Integer内部实际上是做了如下操作:

    Integer integer2 = Integer.valueOf(10);

    这时我们查看Integer源码中关于valueOf方法的定义:

    public static Integer valueOf(int paramInt)
      {
        if ((paramInt >= -128) && (paramInt <= IntegerCache.high)) {
          return IntegerCache.cache[(paramInt + 128)];
        }
        return new Integer(paramInt);
      }

    这里我们会留意到”IntegerCache”这个类,跟踪一下代码,发现这是Integer的一个私有内部类,声明如下:

    private static class IntegerCache
      {
        static final int low = -128;
        static final int high;
        static final Integer[] cache;
    
        private IntegerCache() {}
    
        static
        {
          int i = 127;
          String str = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
          if (str != null) {
            try
            {
              int j = Integer.parseInt(str);
              j = Math.max(j, 127);
              i = Math.min(j, 2147483518);
            }
            catch (NumberFormatException localNumberFormatException) {}
          }
          high = i;
          cache = new Integer[high - -128 + 1];
          int k = -128;
          for (int m = 0; m < cache.length; m++) {
            cache[m] = new Integer(k++);
          }
          assert (high >= 127);
        }
      }
    }

    这段代码并不难读,这里类缓存了从-128到127之间的所有整型对象,意思是当使用自动装箱的方式定义一个值在-128到127的Integer对象时,我们得到的是从缓存区(IntegerCache)中返回的实例。

    所以,当我们在进行上面的第三次比较时,此时的integer1和integer2是同一个对象,那么比较的结果当然是true啦。第四次是因为我们指定的值为128,>127,所以Integer内部会创建新的对象返回,所以当然不可能相等。

    最后啰嗦一下,如果要进行两个Integer对象基于数值的比较时,因为Integer实现了Compaeable接口,所以直接使用compaerTo方法进行比较会比较妥当。判等的话还可以使用equals方法,于是我们把最开始的代码改成如下:

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        Integer integer1;
        Integer integer2;
    
        integer1 = new Integer(10);
        integer2 = new Integer(10);
        //第一次比较
        //System.out.println("第一次比较:"+(integer1==integer2));
        if(integer1.equals(integer2))
            System.out.println("第一次比较:"+true);
        else
            System.out.println("第一次比较:"+false);
    
        //第二次比较
        System.out.println("第二次比较:"+(integer1==10));
    
        integer1 = 127;
        integer2 = 127;
        //第三次比较
        //System.out.println("第三次比较:"+(integer1==integer2));
        if(integer1.equals(integer2))
            System.out.println("第三次比较:"+true);
        else
            System.out.println("第三次比较:"+false);
    
        integer1 = 128;
        integer2 = 128;
        //第四次比较
        //System.out.println("第四次比较:"+(integer1==integer2));
        if(integer1.equals(integer2))
            System.out.println("第四次比较:"+true);
        else
            System.out.println("第四次比较:"+false);
    }
  • 相关阅读:
    什么是知行动手实验室?
    SpringBoot Admin2.0 集成 Java 诊断神器 Arthas 实践
    一文读懂容器存储接口 CSI
    AI 事件驱动场景 Serverless 实践
    一不小心,它成为了 GitHub Alibaba Group 下 Star 最多的开源项目
    5G 和云原生时代的技术下半场,视频化是最大最新的确定性
    基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台
    Knative 基于流量的灰度发布和自动弹性实践
    阿里的 RocketMQ 如何让双十一峰值之下 0 故障?
    阿里巴巴开源容器镜像加速技术
  • 原文地址:https://www.cnblogs.com/crazylqy/p/10482521.html
Copyright © 2020-2023  润新知