背景
本周开发中遇到一个很低级的问题,Integer包装类的相等判断,包装类与基本数据类型的区别,应该大多数人在面试中经常被问到,但是有的时候大家都会烦这些看起来没啥用的东西,面试前还需要去熟悉,博主之前也是这样认为的,但是平时看一些理论性的东西,在方案探讨或者可行性分析时是很必要的,废话不多少,看看这个问题吧
事故现场
public static void main(String[] args) { Integer a =127; Integer b = 127; Integer c = 128; Integer d = 128; Integer e = 129; Integer f = 129; System.out.println(a==b); //true System.out.println(c==d);//false System.out.println(e==f);//false System.out.println(a.equals(b));//true System.out.println(c.equals(d));//true System.out.println(e.equals(f));//true }
分析原因
上面例子中可以看到127的比较使用==是可以的,128和129就不可以,这种情况去看看Integer是怎么处理的。
打开Integer类全局搜索一下127这个数字,为啥要搜这个127,因为127是可以的,128就不行,Integer肯定是对127做了特殊处理,搜了一下之后,果然有发现这个数字都集中在一个叫做IntegerCache内部类中,代码如下:
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ 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() {} }
看这个内部类的描述翻译过来为:
按照java语义规范要求,缓存以支持值在-128到127(包含)范围内的自动装箱对象的初始化
缓存在第一次使用时初始化,缓存的大小由选项{@code -XX:AutoBoxCacheMax=<size>}控制,在虚拟机初始化期间,java.lang.Integer.IntegerCache.high参数或被复制并且保存在sun.misc.VM类的私有系统变量中
通俗的来说就是,在-128到127的范围内,Integer不对创建对象,而是直接取系统缓存中的变量数据。
解决
针对包装类最好全部使用equals进行判断,Integer得equals方法如下:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
判断类型后,将其装换成int值进行大小的判断,并返回结果
反思
一些理论虽然平时不是很有,但是如果对理论理解不到位,出现理解偏差,这种情况下产生的问题,一般走查代码是很难排查出问题的。
总结
到此这篇关于Java中Integer类型值相等判断方法的文章就介绍到这了,更多相关Java Integer类型值相等判断内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!