【问题标题】:How != and == operators work on Integers in Java? [duplicate]!= 和 == 运算符如何处理 Java 中的整数? [复制]
【发布时间】:2012-04-07 02:51:18
【问题描述】:

下面的代码让我很困惑,因为它提供了两种不同的输出。代码在 jdk 1.7 上测试过。

public class NotEq {

public static void main(String[] args) {

    ver1();
    System.out.println();
    ver2();
}

public static void ver1() {
    Integer a = 128;
    Integer b = 128;

    if (a == b) {
        System.out.println("Equal Object");
    }

    if (a != b) {
        System.out.println("Different objects");
    }

    if (a.equals(b)) {
        System.out.println("Meaningfully equal.");
    }
}

public static void ver2() {
    Integer i1 = 127;
    Integer i2 = 127;
    if (i1 == i2) {
        System.out.println("Equal Object");
    }

    if (i1 != i2){
        System.out.println("Different objects");
    }
    if (i1.equals(i2)){
        System.out.println("Meaningfully equal");
    }
}

}

输出:

[ver1 输出]
不同的对象
有意义的平等。

[ver2 输出]
相等对象
有意义的平等

为什么 == 和 != 测试会为 ver1() 和 ver2() 生成不同的结果,而相同的数字远小于 Integer.MAX_VALUE?是否可以断定 == 检查大于 127 的数字(对于像代码中显示的 Integer 这样的包装类)完全是浪费时间?

【问题讨论】:

  • 这是因为自动装箱机制为 -128 - 127 范围内的值缓存和重用相同的对象。这是上一个问题的重复。
  • @quixoto:查看我的编辑回复:)

标签: java integer wrapper operator-keyword equals-operator


【解决方案1】:

为 -128 和 127 之间的值缓存整数,因此 Integer i = 127 将始终返回相同的引用。 Integer j = 128 不一定会这样做。然后您需要使用equals 来测试底层int 是否相等。

这是Java Language Specification的一部分:

如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(包括)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两次装箱转换的结果。 r1 == r2 总是如此。

但是对Integer j = 128 的两次调用可能会返回相同的引用(不保证):

内存限制较少的实现可能会缓存所有 char 和 short 值,以及 -32K 到 +32K 范围内的 int 和 long 值。

【讨论】:

  • 虽然构造函数不使用缓存。试试:System.out.println(new Integer(2) == new Integer(2))
  • new Integer(127) 永远不会返回相同的引用。事实上,它保证总是创建一个新对象。但是当像Integer i = 127; 那样使用自动装箱时,就会使用缓存。顺便说一句,上边界127不是固定的而是最小值。它可以配置为更大的值,但不能更低。
【解决方案2】:

因为 Java 中包含小整数,并且您尝试了“小”限制不同侧的数字。

【讨论】:

  • @downvoter,您愿意详细说明您的投票吗?
【解决方案3】:

默认情况下存在从 -128 到 127 的整数对象缓存。可以配置上边框。上缓存边界可以通过VM选项控制-XX:AutoBoxCacheMax=<size>

您在使用表单时正在使用此缓存:

 Integer i1 = 127;

Integer i1 = Integer.valueOf(127);

但是当你使用

Integer i1 = new Integer(127);

那么你肯定会得到一个新的未缓存对象。在后一种情况下,两个版本都打印出相同的结果。使用缓存的版本,它们可能会有所不同。

【讨论】:

  • 很高兴知道。请不要在生产环境中这样做。
【解决方案4】:

Java 缓存从 -128 到 127 的整数,这就是对象相同的原因。

【讨论】:

    【解决方案5】:

    我认为 == 和 != 运算符在处理原语时将按照您当前使用它们的方式工作,但对于对象(整数与 int),您需要使用 .equals() 方法执行测试。

    我对此不确定,但是对于对象, == 将测试一个对象是否是同一个对象,而 .equals() 将执行测试这两个对象是否包含等价的值(或者该方法将需要为自定义对象创建/覆盖)。

    【讨论】:

      猜你喜欢
      • 2018-09-14
      • 1970-01-01
      • 2015-09-18
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多