• Integer类型比较杂谈


    Integer类型的比较是面试中常问的一个东西, 如果深入了解其中也大有学问, 涉及基本数据类型,引用数据类型的装箱拆箱,类加载机制等,

    首先看下面两段代码的执行结果

    public static void IntegerDemo1() {
                Integer i1 = 100;
                Integer i2 = 100;
                System.out.println(i1.hashCode());
                System.out.println(i2.hashCode());
                System.out.println("比较结果:" + (i1 == i2));
                System.out.println("比较结果:" + i1.equals(i2));
                System.out.println("比较结果:" + i1.compareTo(i2));
            }
        100
        100
        比较结果:true
        比较结果:true
        比较结果:0
    public static void IntegerDemo1() {
                Integer i1 = 200;
                Integer i2 = 200;
                System.out.println(i1.hashCode());
                System.out.println(i2.hashCode());
                System.out.println("比较结果:" + (i1 == i2));
                System.out.println("比较结果:" + i1.equals(i2));
                System.out.println("比较结果:" + i1.compareTo(i2));
            }
       200
        200
        比较结果:false
        比较结果:true
        比较结果:0    

    为什么变量是100和200时会出现上述的结果呢?

    首先要明白Integer i1 = 100做了什么? 在做这样的操作时,实际就是基本数据类型与引用类型之间的拆箱和装箱操作,Integer i1 = 100是一个装箱操作,
    本质就是Integer i1 = Integer.valueOf(100),源码如下,

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

    在valueOf方法,,对赋的值进行一个判断操作,如果值在-128~127之间,就会在内部类IntegerCache的cache[]数组中获取一个Integer对象,
    如果不是就new一个新的Integer对象.

    那么cache[]中又是什么呢?

     cache = new Integer[(high - low) + 1];
     int j = low;
     for(int k = 0; k < cache.length; k++)
         cache[k] = new Integer(j++);

    从IntegerCache中的一段源码中可以发现cache[]中循环放入了值在-128~127之间的Integer对象,根据内部类加载机制,当类第一次
    调用时会初始化这个数组,并且在JVM中只初始化一次,到这里我们就明白了为什么赋值在-128~127之间的比较时能够相等,
    因为==比较的是内存地址,示例代码中的变量i1和i2在这个范围内都引用了从cache取出的同一个对象,对象内存地址一样,
    所以是相等的,在超出这个范围之后,每次创建会new一个新的Integer对象,引用的是不同的对象,所以不相等.

    那为什么equals方法一直相等呢?

    public boolean equals(Object obj) {
            if (obj instanceof Integer) {
                return value == ((Integer)obj).intValue();
            }
            return false;
    }

    可以看到Integer对equals方法进行重写,从比较两个对象的内存地址变成了比较两个Integer对象的的值,这与String类相似,

    同时重写的还有hashCode()方法,hashcode返回了对象的值.

    那为什么要设计IntegerCache类来缓存-128~127的对象呢?

    节省内存消耗,提高程序性能,Integer是一个经常使用到的类,并且一般创建的对象值范围都在-128~127之间,
    并且创建这样相似值的对象并没有太大意义,所以使用IntegerCache类,与此类似的ByteCache、ShortCache等.

    那Integer比较用什么方法呢?

    推荐compareTo方法,其次equals方法

  • 相关阅读:
    vue 中使用 rem 布局的两种方法
    ant design pro请求返回全局参数 ant design pro超详细入门教程
    小程序中页面跳转路由传参
    检查域名所对应的ip
    小程序数据可视化echarts 动态设置数据
    微信小程序:上拉加载更多
    微信小程序接入百度OCR(身份证识别)
    JavaScript鼠标事件,点击鼠标右键,弹出div
    java 相关文件安装
    微信小程序自定义顶部组件customHeader的示例代码 小程序中如何引用阿里图标
  • 原文地址:https://www.cnblogs.com/zhexuejun/p/13157930.html
Copyright © 2020-2023  润新知