简单的Java表达式会返回一些意外结果

时间:2011-11-13 18:38:43

标签: java

以下Java代码中使用的表达式是非常不可接受的,尽管我仅仅为了一般目的而测试它们并获得了一些意想不到的结果。简单的代码片段如下。

package wrapper;

final public class Main 
{
    public static void main(String[] args) 
    {
        Integer j1 = 127;
        Integer j2 = 127;
        System.out.println(j1==j2); //returns true!!!

        Integer k1 = 128;
        Integer k2 = 128;
        System.out.println(k1==k2); //returns false!!!

        Integer w1 = -128;
        Integer w2 = -128;
        System.out.println(w1==w2); //returns true!!!

        Integer m1 = -129;
        Integer m2 = -129;
        System.out.println(m1==m2); //returns false!!!
    }
}

Integer j1 = 127;
Integer j2 = 127;
System.out.println(j1==j2);

上面的代码显然显示 true 因此,毫无疑问。


Integer k1 = 128;
Integer k2 = 128;
System.out.println(k1==k2);

上述代码预计在控制台上显示为true,但令人惊讶的是,它显示 false 。为什么呢?


Integer w1 = -128;
Integer w2 = -128;
System.out.println(w1==w2); 

此代码显示 true ,对此毫无疑问。


Integer m1 = -129;
Integer m2 = -129;
System.out.println(m1==m2);

上面的代码再次显示 false ,但预计会返回true。为什么呢?

5 个答案:

答案 0 :(得分:9)

范围-128..127中的

Integer被缓存,因此j1j2来自:

Integer j1 = 127;
Integer j2 = 127;

指向同一个对象。

当然,这是一个JVM实现的东西,所以你永远不应该假设它们被缓存了。要比较参考类型,请不要使用==,而是使用他们的equals(...)方法。

答案 1 :(得分:4)

请注意

之间存在差异
int k1 = 128;
int k2 = 128;
System.out.println(k1==k2);

Integer k1 = 128;
Integer k2 = 128;
System.out.println(k1==k2);

第一个是创建简单的数字类型。第二个是创建对象类型,它包含数值类型以允许它们传递给期望对象的函数。

在第一种情况下,简单数字类型只有一个值,并且在使用==时进行比较。但是,创建的对象不使用==来比较它们的值。相反,他们使用==来说明它们是否是同一个对象,并使用.equals()方法来说明它们是否具有相同的值。 Java中没有运算符重载,因此任何时候将对象与==进行比较,它总是会问“这是同一个对象吗?”而不是“这两个对象具有相同的价值吗?”

因此,在这种情况下,您提供的代码相当于

Integer k1 = new Integer(128);
Integer k2 = new Integer(128);
System.out.println(k1==k2);

返回false,因为k1和k2不是同一个对象。相反,如果你这样做:

Integer k1 = 128;
Integer k2 = k1;
System.out.println(k1==k2);

你会成真。

实际上,令人惊讶的部分是您上述测试的任何结果都是正确的。这是因为Java为小数字(-128到127,即一个字节大小)保留了一组整数,并在可能时将它们用于分配。

答案 2 :(得分:3)

==运算符检查引用相等性,在上面的代码中不能保证为真。

要比较值是否相等,请使用m1.equals(m2)

答案 3 :(得分:1)

这是因为java的整数缓存,因为你使用的是==运算符而不是equals()。

使用==表示比较对象的引用。

整数A = 135; 整数B = 135;

A == B将评估他们的引用是否相同(它们是否是同一个对象),而不是它们是否相等。

此外,如果A和B在(-128,127)之间,它们被缓存 - 意味着如果A和B是35,它们实际上将是相同(缓存)的对象,这就是为什么你得到A == B如果yhey在上面的范围内。

在这种情况下使用equals。

答案 4 :(得分:1)

因为将对象与==运算符进行比较是不正确的,该运算符比较非基本类型的对象引用。 ==运算符可以比较原始类型。必须使用equals方法比较引用类型(Integer,Float,Double和其他对象)。

有时==可能对Integer这样的类型起作用的原因是内部缓存。当你声明这样的整数时:

Integer i = 10;

相当于:

Integer i = Integer.valueOf(10);

对于-128到127之间的值,该值是从缓存中获取的,这意味着后续调用将返回相同的对象。

但如果你试试这个:

Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.out.println(i1 == i2); // prints false

您将有两个不同的对象,它们的引用不相等。要获得正确的结果,您应该按如下方式对它们进行比较:

Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.out.println(i1.equals(i2)); // prints true

您应该阅读equalshashCode方法以及它们之间的合同