如何使用“instanceof”为泛型实现“equals”方法?

2022-09-01 15:50:45

我有一个接受泛型类型的类,我想以一种不尴尬的方式重写该方法(即看起来干净且代码量最少的东西,但对于非常通用的用例)。equals

现在我有这样的东西:

public class SingularNode<T> {
    private T value;

    @SuppressWarnings("unchecked")
    @Override
    public boolean equals(Object other){
        if(other instanceof SingularNode<?>){
            if(((SingularNode<T>)other).value.equals(value)){
                return true;
            }
        }
        return false;
    }
}

我猜,这是非常有缺陷的 - 我正在对对象进行强制转换,这可能会引发错误SingularNode<T>other

另一件事是 - 当我这样做时,我实际上并没有检查完全正确的东西。我实际上想检查类型而不是类型。每当我试图做成,我得到一些错误,如:if(other instanceof SingularNode<?>)T??T

无法对参数化类型 SingularNode<T> 执行实例检查。请改用 SingularNode<?>的形式,因为将在运行时擦除进一步的泛型类型信息

我该如何解决这个问题?有没有办法做到?T.class.isInstance(other);

我想有一个非常丑陋的黑客解决方案,就像这样:

@SuppressWarnings("unchecked")
public boolean isEqualTo(Class<?> c, Object obj){
    if(c.isInstance(obj) && c.isInstance(this)){
        if(((SingularNode<T>)obj).value.equals(value)){
            return true;
        }
    }
    return false;
}

但是,使用额外的方法参数,这看起来真的很尴尬,而且它也不是像us那样的内置函数。equals

任何了解泛型的人请解释一下吗?正如你所看到的,我对Java并不那么精通,所以请更详细地解释一下!


答案 1

此版本未发出警告

public boolean equals(Object other){
    if (other instanceof SingularNode<?>){
        if ( ((SingularNode<?>)other).value.equals(value) ){
            return true;
        }
    }
    return false;
}

至于投射到它没有任何帮助,你不能假设它可以是任何东西,除了.SingularNode<T>TObject

了解有关如何在 Java 中编译泛型的更多信息,请访问

https://docs.oracle.com/javase/tutorial/java/generics/erasure.html


答案 2

Evgeniy的解决方案Michal的推理是正确的 - 你不需要担心这里的类型。原因是 equals 方法不依赖于泛型来正常工作。相反,它由 声明,并采用 .因此,它负责检查传入任何内容的运行时类型。TObjectObject

如果碰巧是,并且您将其与 一个 进行比较,那么是完全可以的,因为使用参数调用将正确返回 。thisSingularNode<String>SingularNode<Integer>((SingularNode<?>)other).value.equals(value)Integer.equalsStringfalse