我有一个接受泛型类型的类,我想以一种不笨拙的方式重写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;
}
}
我猜,这是非常有缺陷的-我在other
对象上对SingularNode<T>
进行强制转换,这可能会抛出错误。
另一件事是-当我做if(other instanceof SingularNode<?>)
时,我实际上并没有检查正确的东西。我实际上想检查的是T
类型,而不是?
类型。每当我尝试将?
转换为T
时,我都会遇到一些错误,比如:
无法对参数化类型执行instanceof检查请使用**
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;
}
但是使用额外的方法参数看起来真的很笨拙,而且它也不是像equals
那样的内置函数。
有没有懂泛型的人可以解释一下?您可以清楚地看到,我对Java不是很精通,所以请更详细地解释一下!
发布于 2013-05-05 17:23:58
此版本不提供任何警告
public boolean equals(Object other){
if (other instanceof SingularNode<?>){
if ( ((SingularNode<?>)other).value.equals(value) ){
return true;
}
}
return false;
}
至于转换为SingularNode<T>
没有任何帮助,你不能假设T
可以是Object
以外的任何东西。
了解有关如何在Java中编译泛型的更多信息,请访问
https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
发布于 2013-05-06 00:08:46
Evgeniy's solution和Michal's reasoning是正确的-你不需要担心这里的T
类型。原因是equals
方法不依赖于泛型才能正常工作。相反,它是由Object
声明的,它接受一个Object
。因此,它负责检查传入的任何内容的运行时类型。
如果this
恰好是SingularNode<String>
,并且您将其与SingularNode<Integer>
进行比较,那么((SingularNode<?>)other).value.equals(value)
完全没有问题,因为使用String
参数调用Integer.equals
将正确地返回false
。
发布于 2013-05-05 17:18:07
我把答案放在这里是为了把代码..
在您的示例中,您有(以伪代码形式) Integer(5).equals(Char('k'))
,它是false
,根据java.lang.Integer
上的以下equals实现
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
这样一来,你就不必担心选角问题了。
https://stackoverflow.com/questions/16382887
复制相似问题