【问题标题】:Why == in case of Integer check for value not reference in java , case different with new operator为什么 == 在 Integer 检查值而不是 java 中引用的情况下,与 new 运算符的情况不同
【发布时间】:2017-01-10 09:26:17
【问题描述】:

我们知道 == 在 Objects 的情况下,如果指向同一个引用,则返回 true,否则返回 false。

所以,如果我采取了

    Integer a = new Integer("1"); // Creating Integer Object a
    Integer b = new Integer("1"); // Creating Integer Object b

然后执行 a == b ,然后返回 true 但他们都有不同的参考。

【问题讨论】:

标签: java


【解决方案1】:

JVM 缓存 -127 到 127 之间的整数值。
这就是 == 适用于此范围之间的整数值的原因。

但是:

Integer i1=new Integer("11");
Integer i2=new Integer("11");
System.out.println(i1==i2); //false

Integer i3=11;
Integer i4=11;
System.out.println(i3==i4); //true

Integer i5=128;
Integer i6=128;
System.out.println(i5==i6); //false

【讨论】:

  • 使用new 关键字时,必须创建并返回一个新对象。在这种情况下,缓存不起作用。
  • 这是否意味着JVM缓存作为字符串常量池工作?
  • 不完全是字符串池,因为没有新的整数被添加到这个缓存中,整数类使用享元模式,即 Integer.valueOf(..),它将从这个缓存中返回整数值。
【解决方案2】:

因为它被覆盖了。 source

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

【讨论】:

  • 但我们不是在谈论equals方法!
  • 你是对的。这是关于相同的解释 - docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.21 - 它说 - 相等运算符可用于比较可转换(第 5.1.8 节)为数字类型的两个操作数,或布尔或布尔类型的两个操作数,或两个操作数,每个操作数都是引用类型或空类型。所有其他情况都会导致编译时错误。
【解决方案3】:

让我更详细地说明这一点,@asAmit Bhati 在我们写作时的回答中说

    Integer i1=new Integer("11");
    Integer i2=new Integer("11");
    System.out.println(i1==i2); //false

jvm 创建两个单独的对象并将它们与“==”进行比较会导致错误。但是当我们编写以下代码时:

    Integer i3=11;
    Integer i4=11;
    System.out.println(i3==i4); //true

它会被翻译成这样:

    Integer i3=Integer.valueOf(11);
    Integer i4=Integer.valueOf(11);

valueOf方法的实现如下(java 1.8):

    public static Integer valueOf(int var0) {
    return var0 >= -128 && var0 <= Integer.IntegerCache.high?Integer.IntegerCache.cache[var0 + 128]:new Integer(var0);
}

如您所见,如果该值介于 -128 和最大缓存值之间(可以使用此 jvm 参数 -Djava.lang.Integer.IntegerCache.high 进行配置),它将检索缓存值并且不会创建一个新的 Integer 实例,这就是 (==) 对某些值返回 true 的原因!

还要注意,Character Wrapper 类也是如此,但 Float 和 Double 类则不然。

【讨论】:

    【解决方案4】:

    正如上面的答案所说,它可能在许多情况下都有效,但是您不应该将两个 Integer 与 == 进行比较,因为它在某些情况下可能会出现问题。

    查看此答案以获取更多信息:

    Comparing Integer values in Java, strange behavior

    【讨论】:

      【解决方案5】:

      如果您检查 Integer 类中的 equals 方法实现,则为:

      public boolean equals(Object obj) {
          if (obj instanceof Integer) {
              return value == ((Integer)obj).intValue();
          }
          return false;
      }
      

      从这里你可以看到它使用了“==”操作符。

      现在是背后的原因。最终,您必须比较 Integer 包装类的值,这会因为 Java 中的自动装箱和拆箱而自动发生。

      从方法定义中也可以看到,它正在使用((Integer)obj).intValue() 检索传递的Object 值。

      【讨论】:

      • 我不是在问equals方法,我是在问==运算符,这是否意味着当我们调用==时它在内部调用equals方法..
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-08
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2011-03-27
      • 1970-01-01
      相关资源
      最近更新 更多