buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

用int还是用Integer?

昨天例行code review时大家有讨论到int和Integer的比较和使用。 这里做个整理,发表一下个人的看法。
 
【int和Integer的区别】
  • int是java提供的8种原始类型之一,java为每个原始类型提供了封装类(标注:这些封装类被称为"包装类" Wrapper classes),它们位于java.lang包中),Integer是int的封装类。int默认值是0,而Integer默认值是null;
  • 对于 Integer i=*; (标注:*指代一个数字,例如100、1000),java在编译时会将其解释成 Integer i=Integer.valueOf(*); (标注:Integer#valueOf实现逻辑是,如果整数值在缓存范围内,则返回缓存中的对象,否则new一个Integer对象)。这就是所谓的装箱操作。
  • int和Integer(无论是否new)比较,都为true, 因为比较前会先把Integer自动拆箱为int;
  • Integer是引用类型,通常用equals来比较两个Integer。
  • 用==比较两个Integer对象,比较的是它们的内存地址,所以不同的Integer对象肯定是不同的;但是,Integer类缓存了[-128,127]之间的整数, 所以对于Integer i1=127;与Integer i2=127; 来说,i1==i2,因为这二个对象指向同一个内存单元(标注1:也可以描述为表达式 (Integer)127 == (Integer)127 返回true。标注2:表达式  Integer.valueOf(127)== Integer.valueOf(127) 同样返回true。标注3:表达式  new Integer(100) == new Integer(100) 会返回false哦,因为这是显式使用new关键字创建的两个对象是不同的对象,它们引用不同的内存地址)。 而Integer i1=128;与Integer i2=128; 来说,i1==i2为false。
【各自的应用场景】
  • Integer默认值是null,可以区分未赋值和值为0的情况。比如未参加考试的学生和考试成绩为0的学生
  • 方法内部的局部变量,用int;加减乘除和比较运算较多,用int
  • 容器里推荐用Integer。 对于PO实体类,如果db里int型字段允许null,则属性应定义为Integer。————默认也应当定义为包装类型,从而兼容数据为null的情况,规避NPE异常。诸如mybatis这些代码生成器生成的属性就是包装类型,我们从阿里开发规范里也可以找到类似声明———— 当然,如果系统限定db里int字段不允许null值,则也可考虑将属性定义为int。
  • 对于应用程序里定义的枚举类型, 其值如果是整型,则最好定义为int,方便与相关的其他int值或Integer值的比较
  • Integer提供了一系列数据的成员和操作,如Integer.MAX_VALUE,Integer.valueOf(),Integer.compare(),compareTo()。不过一般用得比较少。建议,一般用int类型,这样一方面省去了拆装箱,另一方面也会规避使用equals进行数据比较时可能带来的bug。

【碎碎念→例如,下面几种情况如果不注意,可能会给你的程序带来bug】

  • ①表达式 (Integer)1000 == (Integer)1000返回false。即[-128,127]区间外的Integer用==比较返回false;
  • ②表达式  new Integer(100) == new Integer(100)  会返回false;
  • ③Integer#equals重载自超类Object,入参是Object类型,那么,当入参不是个Integer时,会因数据类型不一致而导致Integer#equals返回false。

【附:Integer类的内部类IntegerCache和valueOf方法代码 

public final class Integer extends Number implements Comparable<Integer> {

	//。。。。。。。。。。。。

    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) {
                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);
            }
            high = h;

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

        private IntegerCache() {}
    }

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

}

 

 

ref:java中申明变量用 int 还是 Integer http://bbs.csdn.net/topics/360102986

ref:Integer与int的种种比较https://www.cnblogs.com/liuling/archive/2013/05/05/intAndInteger.html

posted on 2017-12-12 16:37  buguge  阅读(2143)  评论(0编辑  收藏  举报