【问题标题】:Logical Equality versus Object Reference Equality逻辑相等与对象引用相等
【发布时间】:2016-01-01 18:37:43
【问题描述】:

我正在学习 OCA 8 认证。 Java中的“逻辑相等”是什么意思?

我有这种情况:

String s1 = new String("java");
String s3 = new String("java");
StringBuilder s2 = new StringBuilder("java");
StringBuilder s4 = new StringBuilder("java");

if (s1 == s2)      {    System.out.print("1"); } //error
if (s1.equals(s2)) {    System.out.print("2"); } //false
if (s1.equals(s3)) {    System.out.print("3"); } //true
if (s2.equals(s4)) {    System.out.print("4"); } //false

部分:

对象String 上的方法equals() 被重新定义以将对象的值与另一个对象的值进行比较。因此,当我执行该行时:

if (s1.equals(s3)) {    System.out.print("3"); } 

我有结果 3。

在对象StringBuilder 上,方法equals() 未重新定义,因此它将比较对象引用是否相等。因此,当我执行代码行时:

if (s2.equals(s4)) {    System.out.print("4"); }

我有结果false。

我的问题是:

  • 为什么我执行if(s1 == s2)时会出现编译错误?
  • 为什么我执行s1.equals(s2) 是假的?

【问题讨论】:

  • 您查看过第一部分的编译器错误吗?您不理解错误消息的哪一部分?对于第二个问题,您为什么希望 StringBuilder 等于 String?
  • 我已经阅读了编译器错误(它说它们是 2 个不同的对象)。出于这个原因,我在询问 java 中的逻辑平等。我没有例外 2 对象将相等,但我假设我需要创建 2 个对象的情况,定义相同的方法(其中一个查找值相等,另一个查找引用相等)
  • 如果您没想到这两个对象会相等,我不明白您为什么要问第二个问题。恐怕您的评论通常不清楚:(

标签: java string equals stringbuilder


【解决方案1】:
  • 为什么当我执行 if(s1 == s2) i 时会出现编译错误?

== 运算符是reference equality operator。引用 JLS:

如果无法通过强制转换(第 5.5 节)将任一操作数的类型转换为另一操作数的类型,则会出现编译时错误。

在您的情况下,两个操作数的类型为 String 和 StringBuilder,它们不兼容:String 不能转换为 StringBuilder,反之亦然。

  • 为什么当我执行 s1.equals(s2) 时它是假的?

String 和 StringBuilder 是两种不同的类型。 String 中的 equals() 方法检查给定参数是否也是 String 类型,这里不是这种情况,因此 String 的实例永远不会等于 StringBuilder 的实例。

【讨论】:

  • 什么时候需要考虑两个不同对象是否相等?
  • @liriooliro 你是什么意思?
【解决方案2】:
  1. 为什么当我执行 if(s1 == s2) i 时会出现编译错误?
  2. 为什么当我执行 s1.equals(s2) 时它是假的?
  1. 是的。因为String 不是StringBuilder。你会得到“不兼容的操作数类型 String 和 StringBuilder”(因为 String 不是 StringBuilder)。
  2. 再一次,因为String 不是StringBuilder。您可以使用s1.equals(s2.toString())(即true)。

【讨论】:

    【解决方案3】:

    我才发现原因here。

    1012    public boolean equals(Object anObject) {
    1013        if (this == anObject) {
    1014            return true;
    1015        }
    1016        if (anObject instanceof String) {
    1017            String anotherString = (String)anObject;
    1018            int n = count;
    1019            if (n == anotherString.count) {
    1020                char v1[] = value;
    1021                char v2[] = anotherString.value;
    1022                int i = offset;
    1023                int j = anotherString.offset;
    1024                while (n-- != 0) {
    1025                    if (v1[i++] != v2[j++])
    1026                        return false;
    1027                }
    1028                return true;
    1029            }
    1030        }
    1031        return false;
    1032    }
    

    我很困惑,因为 equals 方法采用了类似参数的对象(为此我认为它在方法内部被视为对象,但我看到它是仅适用于的第二个 if 条件字符串对象(在此我找到了关于逻辑平等的问题的回答)。 谢谢大家

    【讨论】:

      猜你喜欢
      • 2012-06-12
      • 1970-01-01
      • 2023-04-05
      • 2015-07-26
      • 1970-01-01
      • 2012-05-11
      • 2020-07-15
      • 1970-01-01
      • 2021-03-31
      相关资源
      最近更新 更多