在 equals() 方法中测试泛型类型

Testing for generic type in equals() method

我有以下 class.

public class Combination<E extends Comparable> {

    private List<E> objects;

    // ...

    @Override
    public boolean equals(Object o) {
        // ...
    }

    @Override 
    public int hashCode() {
        // ...
    }
}

我正在覆盖 equalshashCode 方法,因此我可以轻松创建 Set<Combination> 而没有任何冗余组合。

问题是...因为我的 class 有一个通用类型,我如何在我的 equals 方法中测试这个类型?例如,Combination<Integer>Combination<Double>Combination<Car> 不同。但是如何在 equals 方法中对此进行测试呢?

理想情况下,我可以覆盖 equals 方法以接受 Combination<E> 参数。一个简单的解决方案是重载 equals 方法吗?例如,

@Override
public boolean equals(Object o) {
    // This method will only be called when o is not an instance of Combination<E>.
    // So in this case return false.
    return false;
}

public boolean equals(Combination<E> cmb) {
    // Compare the two combinations here.
    // <code> ...
}

你不能完全按照你在Java中提出的那样做:

  1. 在 Java 中,泛型在编译类型时被删除,因此您在运行时根本没有类型参数信息
  2. equals() 不能采用与 Object 不同的参数,那将是重载,而不是覆盖

可以轻松实现类似的语义功能。 你应该委托给 objects.equals() from 你的 equals() 方法,如果传递给组合 class 对象的对象正确实现 equals()hashCode()

你把平等的概念过于复杂化了。只需从 equals 方法中分解另一个实例并比较每个成员的有效状态。

public class Foo<T> {
  T field;
  public Foo(T f){
    field = f;
  }

  @Override
  public boolean equals(Object o){
    // leaving off the standard instanceof checking
    Foo other = (Foo)o;
    return field.equals(other.field);
  }
}

这里的解决方案是相信成员对象的 equals 方法只匹配正确的类型。你确实需要在这里使用instanceof,你不应该使用rawtypes,但它应该看起来像

@Override public boolean equals(Object o) {
  if (o instanceof Combination) {
    Combination<?> c = (Combination<?>) o;
    return objects.equals(c.objects);
  }
  return false;
}

这是类型安全的并且工作正常,并且相信 List(及其元素)有自己的 equals 方法的正确实现。