【问题标题】:What happens when you compare two of the same type objects using ==, >, <, etc, in Java? [duplicate]在 Java 中使用 ==、>、< 等比较两个相同类型的对象时会发生什么? [复制]
【发布时间】:2012-09-27 02:50:45
【问题描述】:

可能重复:
Difference Between Equals and ==

例如,如果我有

MyClass foo = new MyClass();
MyClass bar = new MyClass();

if (foo == bar) {
    // do something
}
if (foo < bar) {
    // do something
}
if (foo > bar) {
    // do something
}

foobar 如何比较? Java 是否会寻找为MyClass 实现的.compareTo() 方法? Java 会在内存中逐位比较对象的实际二进制结构吗?

【问题讨论】:

  • 不,它会查看它们是否在内存中占据相同的位置。就这样。这就是为什么你应该使用equal 来比较对象。
  • @assylias:C# 支持运算符重载。 Java 没有。
  • @Eric 我链接到的答案同时涉及 Java 和 C# - 这可能会令人困惑。这是一个更好的链接:stackoverflow.com/questions/2772763/…
  • @RichardJPLeGuen 我看到了编辑,并回滚但随后应用了您的一些更改。问题是,我没有足够的知识以与您相同的方式提出问题,因此没有您知识(关键字、措辞等)的人可能无法使用更简单的术语找到问题。

标签: java conditional


【解决方案1】:

算术比较运算符==!= 非常简单地比较对象引用或对象的内存地址。 &gt;&lt; 及相关运算符不能与对象一起使用。

所以==!= 仅在您想确定两个不同的变量是否指向相同对象时才有用。

例如,这在事件处理程序中很有用:如果您有一个事件处理程序绑定到例如多个按钮,您需要在处理程序中确定 哪个 按钮已被按下。在这种情况下,您可以使用==

使用.equals 等方法或String.compareTo 等特殊用途方法捕获您所询问类型的对象比较。

值得注意的是,默认的Object.equals方法等价于==:它比较对象引用;这在the docs 中有介绍。 Java 内置的大多数类都使用自己的实现覆盖equals:例如,String 覆盖equals 以一次比较一个字符。要为您自己的对象获得更具体/更有用的.equals 实现,您需要使用更具体的实现覆盖.equals

【讨论】:

  • 那么.equals() 比较什么?它是否查看两个对象是否具有相同的方法和属性以及属性是否也相等?或者它只是检查属性是否相等?还是逐点比较?
  • @trusktr default .equals 方法等价于==:它比较引用。很好的后续问题:我会补充回答
  • 看一下字符串中.equals的实现。这是一个好的开始。通常,您首先检查引用相等性 (==),然后检查赋值兼容性(通常使用 instanceof 运算符),最后检查特定于对象的数据比较。在字符串的情况下,它是底层的字符数据。
【解决方案2】:

它比较参考值,只有当foobar指向同一个对象时才会返回true。

【讨论】:

    【解决方案3】:

    不,它没有。它比较两个变量是否是对相同对象的引用。

    除非您处理的是受自动装箱约束的类型,例如Integer,否则您根本不能将&gt;&lt; 用于对象。

    在您使用自动装箱类型的情况下,java 不会查找特定方法,但会自动取消装箱变量,将它们转换为基元 - 但等号运算符并非如此。 == 运算符将始终将对象作为引用进行比较,即使在比较自动装箱对象时也是如此:

        Integer i1 = new Integer(10);
        Integer i2 = new Integer(10);
    
        if(i1 < i2) { // evaluates to false!
            System.out.println("i1 is less than i2");
        }
        else if(i1 > i2) { // evaluates to false!
            System.out.println("i1 is greater than i2");
        }
        else if(i1 == i2) { // evaluates to false!
            System.out.println("i1 and i2 are equal");
        }
        else {
            System.out.println("Um... well that's just confusingi");
        }
    

    【讨论】:

      【解决方案4】:

      在 Java 中,“==”比较对象的身份。 "new" 保证每次都返回一个新的对象标识。

      如果“==”会调用 compareTo,我真的很乐意。唉,它没有。

      【讨论】:

      • 我不会喜欢的。这将是一个巨大的痛苦...您将如何检查两个变量是否指向内存中的同一位置,这意味着它只是一个对象。
      • @MartijnCourteaux 也许类似于if (x.is(y)),其中.is() 将继承自Object 对于所有对象。如果x==y 使用compareTo 来返回truefalse,我更愿意。
      • 我相信 Groovy(也许还有 ActionScript)使用 == 来表示相等,使用 === 来比较引用。
      • @MartijnCourteaux 当然使用反射。毕竟,这是一种反射特性。
      【解决方案5】:

      显然,您自己没有尝试过,因为 &lt;&gt;&lt;=&gt;= 不适用于对象。

      但是,== 比较左右操作数。当它们的二进制相同时,结果为真。对于对象,in 比较指针。所以这意味着这将只有如果对象在内存中的左右是同一个对象,则结果为真。

      其他方法,如 compareTo 和 equals 是为了提供一种自定义方法来比较内存中的不同对象,但它们可能彼此相等(即数据相同)。

      如果是字符串,例如:

      String str0 = new String("foo");
      String str1 = new String("foo");
      
      // A human being would say that the two strings are equal, which is true
      // But it are TWO different objects in memory. So, using == will result
      // in false
      
      System.out.println(str0 == str1); // false
      
      // But if we want to check the content of the string, we can use the equals method,
      // because that method compares character by character of the two objects
      
      String.out.println(str0.equals(str1)); // true
      String.out.println(str1.equals(str0)); // true
      

      【讨论】:

      • 你说得对,我没有尝试 ,但就我而言,我只是在比较平等。感谢您提供的信息。
      猜你喜欢
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 2019-05-29
      相关资源
      最近更新 更多