Dav*_* T. 19 java oop generics equals instance
我有一个接受泛型类型的类,我想以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;
}
}
Run Code Online (Sandbox Code Playgroud)
我猜,这是非常有缺陷的 - 我正在SingularNode<T>对other对象进行强制转换,这可能会引发错误.
另一件事是 - 当我这样做时,if(other instanceof SingularNode<?>)我实际上并没有检查正确的事情.我实际上想要检查类型T而不是类型?.每当我尝试?进入时T,我会得到一些错误:
无法对参数化类型执行instanceof检查
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;
}
Run Code Online (Sandbox Code Playgroud)
但是使用额外的方法参数看起来真的很尴尬,而且它也不是像equalsis 那样的内置函数.
任何了解仿制药的人都请解释一下吗?我不是那么精通Java,你可以清楚地看到,所以请稍微详细解释一下!
Evg*_*eev 21
此版本不提供任何警告
public boolean equals(Object other){
if (other instanceof SingularNode<?>){
if ( ((SingularNode<?>)other).value.equals(value) ){
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
至于铸造SingularNode<T>对它没有任何帮助,你不能认为T可以是任何东西Object.
了解有关如何使用Java编译泛型的更多信息
https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
Evgeniy的解决方案和Michal的推理是正确的 - 你不必担心T这里的类型.原因是该equals方法不依赖于泛型来正常工作.相反,它是由声明Object,它需要一个Object.因此,它负责检查传入的任何内容的运行时类型.
如果this恰好是SingularNode<String>你并将它与a进行比较SingularNode<Integer>,那么((SingularNode<?>)other).value.equals(value)完全没问题,因为Integer.equals使用String参数调用将正确返回false.