`

两个值相同的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
分享到:
评论
1 楼 fdyo3 2014-02-10  
高手

相关推荐

    JAVA Integer == equal 比较 doc 比较大小 是否相等

    因此,当我们使用 "==" 运算符来比较两个 Integer 对象时,实际上是在比较这两个对象的引用是否相同,而不是比较它们的实际值。 例如,在下面的代码中: ```java Integer i1 = 100; Integer i2 = 100; if (i1 == i2...

    java程序中容易出错的地方

    由于浮点数的存储方式,直接使用`==`来比较两个浮点数可能会导致错误的结果。例如: ```java double x = 0.1 + 0.2; double y = 0.3; System.out.println(x == y); // 输出 false ``` 这是因为`0.1`和`0.2`不能精确...

    ASP技术常遇问题解答-如何解决“cint和clng的溢出出错”问题?.zip

    这两个函数,cint和clng,是ASP中用于类型转换的内置函数,它们分别用于将变量转换为整数(Integer)和长整型(Long)。当尝试转换的数值超出这些数据类型的范围时,就会发生溢出错误。在本文中,我们将深入探讨这个...

    springmybatis

    1. 在MyBatis 里面创建两个源码目录,分别为 src_user,test_src, 用如下方式建立,鼠标右键点击 JavaResource. 2. 设置mybatis 配置文件:Configuration.xml, 在src_user目录下建立此文件,内容如下: 程序代码 程序...

    《你必须知道的495个C语言问题》

    3.14 如果我不使用表达式的值,那我应该用i++还是++i来做自增呢? 39 3.15 我要检查一个数是不是在另外两个数之间,为什么if(a b c)不行? 40 3.16 为什么如下的代码不对?int a=1000, b=1000; long int c=a * ...

    Java泛型的理解与等价实现.docx

    在泛型中,类型参数通常用大写字母T表示,但也可以使用其他任何非保留字。例如,`&lt;T&gt;`表示一个未指定的具体类型,它可以在类、接口或方法中代表一个类型占位符。泛型的主要好处在于编译时的类型检查,避免了运行时的...

    C语言程序设计标准教程

    应该把变量的值和变量的地址这两个不同的概念区别开来。变量的地址是C编译系统分配的,用户不必关心具体的地址是多少。 变量的地址和变量值的关系如下: &a---&gt;a567 a为变量名,567是变量的值,&a是变量a的地址。在...

    阶乘(delphi)

    在Delphi中,由于整数溢出的可能性,对于较大的n值,建议使用Int64类型来存储阶乘结果,以避免计算过程中数据溢出的问题。同时,考虑到阶乘增长迅速,即使是Int64也有其局限性,对于超过12!以上的数值,需要使用其他...

    java之java类型转换

    在 Java 中,类型转换非常重要,正确地使用类型转换可以提高程序的效率和可读性,而错误地使用类型转换可能会导致程序出错。因此,程序员需要了解 Java 中的类型转换规则,正确地使用自动转换和强制转换来提高程序的...

    VB简单编程题.pdf

    计算两个电阻并联后的值: ```vb Private Sub Command1_Click() Dim R1 As Double, R2 As Double, R3 As Double R1 = CDbl(Text1.Text) R2 = CDbl(Text2.Text) R3 = 1 / (1 / R1 + 1 / R2) Text3.Text = ...

    vb数据类型

    因为32768超出了Integer的范围,所以第二个例子中的代码会出错,因为Integer类型不能存储32768。 示例2中,第一段代码将两个文本框的文本合并成一个字符串并打印出来,而第二段代码试图将文本框的文本(字符串)与...

    powerbuilder

    用PrintOpen()函数打开的打印作业号fontnumber:指定赋给当前定义字体的编号,有效值在1到8之间 facename:string类型,指定字体名称,该字体应该是你的打印机支持的字体,比如“宋体”height:Integer类型,使用...

    c语言学习第1章-(1)完整.pptx

    `scanf`函数用于从标准输入读取两个整数的值,并将它们分别存储在`integer1`和`integer2`中。`sum`变量用于存储两数之和。最后,`printf`函数将结果输出到标准输出。 此外,C程序还可以包含自定义函数,例如`max()`...

    ASP验证控件详解

    其中,Type 属性指定要比较的控件的数据类型,Operator 属性指定比较操作,ControlToValidate 和 ControlToCompare 属性指定要比较的两个控件的 ID。 例如,我们可以使用 CompareValidator 来检查用户输入的年龄...

    java面试宝典

    `==` 用于比较两个对象的引用是否相等,而 `equals` 方法用于比较两个对象的内容是否相等。对于基本数据类型,`==` 比较的是它们的值是否相等。 **12. 静态变量和实例变量的区别?** - **静态变量**:属于类级别的...

    java面试宝典2010版

    10. **"=="和equals的区别**:"=="比较的是两个对象的引用是否相同,而equals方法比较的是对象的内容是否相等。对于非原始类型,重写equals方法是常见的做法。 11. **静态变量和实例变量**:静态变量属于类,所有类...

    Java核心知识1:泛型机制详解.pdf

    在非泛型编程中,将简单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作,这两个过程都是具有很大开销的。引入泛型后,就不必进行Boxing和Unboxing操作了,所以运行效率相对较高,特别在对集合操作...

    C#验证控件的使用关于控件

    **CompareValidator**控件用于比较两个输入值是否相等或者一个输入值与特定值的关系。这种验证对于确保密码与确认密码一致、年龄在特定范围内等情况非常有用。 ##### 属性设置 - **ControlToCompare**: 设置要比较...

    js中表单验证的简化

    上述代码中,`vf-rule`设置了两个验证规则:`required`表示必填,`email`表示必须是合法的电子邮件格式。如果验证失败,`vf-message`会显示相应的错误信息。 此外,`validform`还提供了全局配置选项,如`onError`和...

    Java面试宝典2011版及答案.doc

    每个`char`占用两个字节,足以表示大部分常用汉字。 8. 计算2乘以8最有效率的方法是直接使用`*`运算符:`2 * 8`。 9. 设计一个一百亿的计算器要考虑数值溢出问题,可以使用`BigInteger`类来处理大整数计算。 10. ...

Global site tag (gtag.js) - Google Analytics