如何使用“instanceof”实现generics的“equals”方法?
我有一个接受generics类型的类 ,我想以一种非笨拙的方式覆盖equals
方法(即看起来很干净并且代码量很少的东西,但对于非常一般的用例)。
现在我有这样的事情:
public class SingularNode { private T value; @SuppressWarnings("unchecked") @Override public boolean equals(Object other){ if(other instanceof SingularNode){ if(((SingularNode)other).value.equals(value)){ return true; } } return false; } }
我猜,这是非常有缺陷的 – 我正在对other
对象的SingularNode
进行强制转换,这可能会引发错误 。
另一件事是 – 当我这样做if(other instanceof SingularNode)
我实际上并没有检查到正确的东西。 我实际上想检查类型T
而不是类型?
。 每当我试图制作?
进入T
,我得到一些错误:
无法对参数化类型
SingularNode
执行instanceof检查。 请改为使用SingularNode
forms,因为在运行时将删除其他generics类型信息
我怎么能绕过这个? 有没有办法做T.class.isInstance(other);
?
我想有一个非常难看的黑客解决方案是这样的:
@SuppressWarnings("unchecked") public boolean isEqualTo(Class c, Object obj){ if(c.isInstance(obj) && c.isInstance(this)){ if(((SingularNode)obj).value.equals(value)){ return true; } } return false; }
但是使用额外的方法参数看起来真的很尴尬,而且它也不像equals
是内置函数。
任何了解仿制药的人都请解释一下吗? 我不是那么精通Java,你可以清楚地看到,所以请稍微详细解释一下!
此版本不提供任何警告
public boolean equals(Object other){ if (other instanceof SingularNode>){ if ( ((SingularNode>)other).value.equals(value) ){ return true; } } return false; }
至于转换为SingularNode
它没有任何帮助,你不能假设T
可以是除了Object
任何东西。
了解有关如何使用Java编译generics的更多信息
https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
Evgeniy的解决方案和Michal的推理是正确的 – 你不需要担心这里的T
类型。 原因是equals
方法不依赖于generics来正常工作。 相反,它由Object
声明,它需要一个Object
。 因此,它负责检查传入的任何内容的运行时类型。
如果this
恰好是SingularNode
并且你将它与SingularNode
进行比较,则((SingularNode>)other).value.equals(value)
完全正常,因为使用String
参数调用Integer.equals
将正确返回false
。
我把答案放在这里放代码..
在你的例子中,你有(伪代码) Integer(5).equals(Char('k'))
,这是false
,根据以下等于java.lang.Integer
实现:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
这样,你不必担心投射。
我有同样的问题,但它更一般。 我有一个class级,我有3个generics类型。 我不需要存储这些类型的任何变量,因为此类用于转换。 但是存在“请求”变量,我确实使用基于此类的缓存,因此我需要实现基于这些generics的equals()方法。
你知道在没有反思的情况下是否有任何方法可以做到这一点? 也许那种类型的内部变量..然而它是null。
public class TheClass { private ClassA param1; private ClassB param2; private ClassC param3; private BiFunction, I, Optional> mapping; public ClassD doSomething(ClassD param) { ... } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null) { return false; } if (getClass() != o.getClass()) { return false; } TheClass, ?, ?> that = (TheClass, ?, ?>) o; return Objects.equals(getParam1(), that.getParam1()) && Objects.equals(getParam2(), that.getParam2()) && Objects.equals(getParam3(), that.getParam3()); } }
为了更好的想象……我有一组DAO对象从数据库中获取数据。 另一方面,我们确实有另一组API提供程序,它们以不同的格式提供类似的数据(REST,内部系统……)我们需要从一种类型到另一种类型的映射函数。 我们使用缓存来获得更好的性能,而这个类中唯一的中间人。
你不需要使用任何铸件。 最好等于实现我看到这样
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof VehicleModel)) return false; VehicleModel that = (VehicleModel) o; if (vehicleName != null ? !vehicleName.equals(that.vehicleName) : that.vehicleName != null) return false; return true; }