【问题标题】:Class compare vs instanceof in equals method java在equals方法java中类比较vs instanceof
【发布时间】:2018-01-28 19:53:24
【问题描述】:

就像在标题中一样: 我的实体如下所示:

@Entity
public class Example {

    @Id
    private Integer id;
    private String name;

    // fields, getters & setters ommited 

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Example example = (Example) o;

        return id != null ? id.equals(examle.id) : examle.id == null;
    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;
    }
}

自动生成的equals方法如上所示。

我的问题是:

  1. 为什么需要手动替换:

o == null || getClass() != o.getClass()

进入

!(o instanceof 示例)

  1. 如果将此类的对象放在 java.util.Set 中会发生什么?哪些部分会违反合同规则?

【问题讨论】:

  • 1. 为什么确实如此?
  • 你不需要更换它。
  • 在实体的情况下看起来不一样。

标签: java spring object entity equals


【解决方案1】:

主要区别在于,如果 o 继承了对象,instanceof 将返回 true,而 getClass 比较将检查两个对象是否严格相同。

【讨论】:

  • 好的,现在我看到了区别。但是你能回答我的第二个问题吗?
【解决方案2】:

根据经验,在您自己的课程中使用它几乎总是更好

if (o == null || getClass() != o.getClass()) return false;

当您计划创建您的类的子类并覆盖equals 时尤其如此,而且当您不打算毫无问题地工作时(在大多数情况下)也是如此。所以你不需要手动替换任何东西。

原因如下。 equals 方法需要在对象上引入等价关系,特别是它应该是对称的:如果 a.equals(b) 它也必须是 b.equals(a) 的情况,反之亦然。许多使用equals 方法的类(例如映射和集合)都采用这种行为。

现在,假设您将o == null || getClass() != o.getClass() 替换为!(o instanceof Example),并创建一个子类如下:

class Subclass extends Example {
    String address;
    // fields, getters and setters
    public boolean equals(Object o) {
        if (!o instanceof Subclass) {
            return false;
        } else {
            return super.equals(o) && Objects.equals(((Subclass)o).address, address);
        }
    }
}

现在考虑以下代码:

Example a = new Example(); 
a.setId(1);
a.setName("A");
Subclass b = new Subclass();
b.setId(1);
b.setName("A");
b.setAddress("Street 1");
System.out.println(a.equals(b)); // Prints true
System.out.println(b.equals(a)); // Prints false

您现在有一个不对称的equals 方法,这可能会导致使用集合时出现问题。

但是请注意,在某些 情况下,您实际上想要使用instanceof。例如,接口Setequals 方法的Javadoc 指定当两个集合包含相同的元素时它们被认为是相等的。因此,如果 HashSet 包含相同的元素,则它们等于 TreeSet,即使这两个集合属于不同的类。在这种情况下,当然不适合使用getClass() == o.getClass()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-26
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多