两个值相同的Integer类型用!=比较出错的问题

有这么一行代码
newInvoiceNumbertarget.getAgency().getSuperiorAgency().getId() != cuttentAgency.getId()
不等号的两边,全部都是34,这个表达式的结果是false,如果两边的值都是765454的话,结果就是true,很奇怪,百思不得其解,问带我的同事大哥,他说如果是Integer类型的话,用!=来比较两个值,是不严谨的,比如刚才的情况,如果是34,返回结果就是false,而如果是特别大的数,如765454,就会出现true,这个情况不常注意,但是是一个漏洞,而要是想知道其中原理,就得好好看看jdk提供的Integer.class类,在里面,定义了,初始化Integer类的一个上限和下限,比如
public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }
这一段代码,以这个为例,这是一个设置Integer缓存的代码,如果在初始化的时候,值出在这个区间,那么就直接初始化,如果大于这个区间的话,就会对他加一个缓存,不一定就是这一段,在初始化一个Integer的时候,比如说我的上限和下限分别是128和-127,那么我的34处于这个区间,他就会当成一个int的值,也就是一个变量,放到内存中,而如果是765454这样大的值,才真正初始化成为Integer对象,然后将值封装进去,而在比较的时候,765454的两个Integer是两个不同的对象,有不同的存储空间,那肯定用!=号是比较不出来值的,而如果是34,那么他实际上比较的是变量,而765454比较的是对象,所以就会出现上面的问题
这个我想也肯定是为了优化考虑,还有就是对象的应用,如果一个系统中大量的用到Integer类型,那么就要设置一下jvm或者jdk中队Integer类型的上限和下限的值,这样的话,比如说,将上限放到1000,原来的情况中,如果大于128的话就会初始化为对象,然后存储,现在大于128小于1000的还是弄成变量,大于1000的才生成对象,当然对象和变量在内存中的存储大小是有着天壤之别的,而且系统大量用到Integer,并且我们能设置的话,就会为系统省去很多的内存,优化,java强大之处,我才只挖到一角
回过来,原理弄完了,问题知道了,就要解决了
解决方法还是很多的,因为我们用!=有可能比较的是变量,也有可能比较的是对象,所以,我们在比较Integer类型的时候,尽量不适用!=,当然int中肯定不用担心这个,我们可以对两个Integer对象进行eqauls比较,因为两个Integer都是对象,而equals又恰好只比较值,不比较对象,所以返回结果肯定是自己想要的,另外一种就是
public boolean equals(Object obj) {
if (obj instanceof Integer) {
    return value == ((Integer)obj).intValue();
}
return false;
    }
jdk中Integer的equals
这个里面的底层也是用intValue来比较的,所以我们在进行比较的时候,也可以用Integer i=234;i.intValue()这样来取值,然后!=比较不会有问题,OK

你可能感兴趣的:(Integer)