zoukankan      html  css  js  c++  java
  • 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方法

  • 相关阅读:
    字体向上滚动
    地图改变图层
    移动地图
    [转] nodejs安装不了和npm安装失败的解决方法
    git回滚merge
    处理网站缓存问题
    webpack初学笔记 之 小案例篇demo1
    正则表达式整理
    关于返回值为图片 音频 视频的处理
    jquery ui datepicker 插件如何设置只能选择日期 禁止输入日期
  • 原文地址:https://www.cnblogs.com/zhexuejun/p/13157930.html
Copyright © 2011-2022 走看看