Java 如何实施";等于;泛型方法使用;instanceof";?
我有一个接受泛型类型的类,我想以一种非笨拙的方式重写Java 如何实施";等于;泛型方法使用;instanceof";?,java,oop,generics,instance,equals,Java,Oop,Generics,Instance,Equals,我有一个接受泛型类型的类,我想以一种非笨拙的方式重写equals方法(即,看起来干净,代码量最少,但用于非常通用的用例) 现在我有这样的事情: public class SingularNode<T> { private T value; @SuppressWarnings("unchecked") @Override public boolean equals(Object other){ if(other instanceof S
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;
}
}
@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
is那样的内置函数
任何理解泛型的人请解释一下?正如您可以清楚地看到的那样,我对Java不是很精通,所以请更详细地解释一下 我把答案放在这里是为了写代码 在您的示例中,根据
java.lang.Integer
上的以下equals实现,您有(在伪代码中)Integer(5).equals(Char('k')),它是false
:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
这样你就不必担心铸造了。这个版本没有警告
public boolean equals(Object other){
if (other instanceof SingularNode<?>){
if ( ((SingularNode<?>)other).value.equals(value) ){
return true;
}
}
return false;
}
公共布尔等于(对象其他){
if(奇点节点的其他实例){
如果(((奇点节点)其他).value.equals(值)){
返回true;
}
}
返回false;
}
至于强制转换到SingularNode
没有任何帮助,您不能假设T
可以是除Object
之外的任何东西
了解有关如何在Java中编译泛型的更多信息,请访问
并且是正确的-您不需要担心这里的t
类型。原因是该方法不依赖泛型来正确工作。相反,它是由对象
声明的,并接受对象
。因此,它负责检查传入内容的运行时类型
如果
此
恰好是SingularNode
,并将其与SingularNode
进行比较,则((SingularNode)other).value.等于(value)
非常好,因为使用字符串参数调用Integer.equals
将正确返回false您不需要使用任何强制转换。
我认为最好的方法就是这样实现
@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;
}
我也有同样的问题,但它更一般。我有一个类,其中我有3个泛型类型。我不需要存储这些类型的任何变量,因为这个类用于转换。然而,存在存储的'request'变量,并且我使用基于此类的缓存,所以我需要实现基于这些泛型的equals()方法
你知道有没有什么方法可以不经思考就做到这一点?可能是那种类型的内部变量。。但是它是空的
public class TheClass<I, O, M> {
private ClassA param1;
private ClassB param2;
private ClassC<M> param3;
private BiFunction<ClassC<M>, I, Optional<O>> mapping;
public ClassD<O, M> doSomething(ClassD<I, M> 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());
}
}
类的公共类{
私人甲级param1;
私人b类2;
私有c类参数3;
私有双函数映射;
公共D类剂量仪(D类参数){
...
}
@凌驾
公共布尔等于(对象o){
if(this==o){
返回true;
}
如果(o==null){
返回false;
}
如果(getClass()!=o.getClass()){
返回false;
}
类=(类)o;
返回Objects.equals(getParam1(),that.getParam1())&&
Objects.equals(getParam2(),that.getParam2())&&
Objects.equals(getParam3(),that.getParam3());
}
}
为了更好的想象力。。。我有一组从数据库获取数据的DAO对象。另一方面,我们有另一组API提供程序,它们以不同的格式提供类似的数据(REST、内部系统..)
我们需要一个从一种类型到另一种类型的映射函数。我们使用缓存来获得更好的性能,中间唯一的人就是这个类。您的错误是因为泛型类型被擦除了。我认为“T”应该负责检查传递的元素是否相同class@MichalBorek嗯,你能详细说明一下吗?我没有完全理解。在另一个类中,如果我这样做:newsingularnode(5).equals(newsingularnode('k'))你知道支票在哪里吗?我加了答案放了一堆代码。哦,好吧,我现在明白你的意思了。非常感谢。出于某种原因,我有一种错误的印象,即当您尝试使用整数强制转换字符时,Java会抛出InvalidClassCast异常
或其他异常。但它只是返回false而不是error。我现在看到了,通常我们首先认为签入equals方法是另一个对象的类,所有Java equals实现都是这样做的。所以在cast(SingularNode)obj
中,实际发生的是它将obj
转换为SingularNode
,而不是T
。这意味着obj.value
实际上是类型T
,对吗?是的。它的类型正是java.lang.Object,因为编译后泛型会被删除。泛型只需要在编译时检查类型安全性(这称为类型擦除)。所以泛型与C++中的模板不同,谢谢你的回答。是的,该代码不会给出任何警告,因为您正在将(SingularNode)other
转换为类型?
,而不是T
。但是,我只想使用T
类型的实例,以防将来我决定用T
类型做一些特殊的事情。如果这有意义的话?我不认为这有意义,因为你不能假设T是物体以外的任何东西,因为它可以是任何东西。如果T扩展了一些东西,可能会有所不同。那么实际上,?
与这里的T
几乎相同?@newacct这是我假设的一个错误。我曾认为,在Java中,如果?
不完全是T
,就会发生糟糕的事情;另外,如果以后我能用T
做点什么,我不希望出现错误,因为我没有键入check有时你无法避免输入