在不知道类型的情况下使用 instanceof
Use instanceof without knowing the type
我的 Java classes 表示数据库中的实体,我发现重写 classes 的 equals
方法以按 id 进行比较很实用.因此,例如在我的 Transaction
class 中,我有这段代码
@Override
public boolean equals(Object other){
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof Transaction))return false;
Transaction otherTrans = (Transaction) other;
if (id == null || otherTrans.id == null) return false;
return id.equals(otherTrans.id);
}
现在对我来说有点丑陋,每个 class 都包含相同的代码段,只是 class 的名称发生了变化。我想过让我的 classes 扩展一个 superclass MyEntity
,我会在其中编写上述方法,用 instanceof this.getClass()
之类的东西替换 instanceof Transaction
,但这并没有似乎是可能的。我也考虑过用 instanceof MyEntity
替换它,但这意味着即使两个对象属于不同的 class,只要它们具有相同的 id,也可以认为它们是相等的。
还有其他办法吗?
您可以使用 instanceof
运算符的动态版本,即 Class
的 isInstance
方法。
Determines if the specified Object is assignment-compatible with the object represented by this Class.
if (!(getClass().isInstance(other))) return false;
这不会阻止 subclass 的实例在 superclass 对象上测试 equals
,而是一种确保它完全相同的动态方法 class 将比较两个 Class
对象是否相等。
if (!(getClass().equals(other.getClass()))) return false;
你可以有一个超级 class 和 equals 方法。
// Where ENTITY would be the type of the class to compare, and ID the type of the id
public abstract class ComparableById<ENTITY extends ComparableById, ID> {
protected abstract Class<?> getEntityClass();
protected abstract ID getId();
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!getEntityClass().isInstance(other)) return false;
ComparableById o = (ComparableById) other;
if (getId() == null || o.getId() == null) return false;
return getId().equals(o.getId());
}
}
然后你可以用这种方式在你的所有 class 中使用它:
@Entity
public class TeacherEntity extends ComparablebyId<TeacherEntity, Long> {
private Long id;
@Override
public Long getId() {
return this.id;
}
@Override
public getEntityClass() {
return this.getClass();
}
}
好处:
+ 避免每个 classes.
中的代码重复
+ 支持所有类型。
+ 没有更多演员。
缺点:
- 您需要为每个 class.
定义 getId()
和 getEntityClass()
方法
我喜欢 rgetmann 的回答 但它不完整。我认为下面的代码(没有以任何方式测试)完成了它。
boolean equals(Object b){
return getClass().equals(b.getClass())
&& id==getClass().cast(b).id;
}
我的 Java classes 表示数据库中的实体,我发现重写 classes 的 equals
方法以按 id 进行比较很实用.因此,例如在我的 Transaction
class 中,我有这段代码
@Override
public boolean equals(Object other){
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof Transaction))return false;
Transaction otherTrans = (Transaction) other;
if (id == null || otherTrans.id == null) return false;
return id.equals(otherTrans.id);
}
现在对我来说有点丑陋,每个 class 都包含相同的代码段,只是 class 的名称发生了变化。我想过让我的 classes 扩展一个 superclass MyEntity
,我会在其中编写上述方法,用 instanceof this.getClass()
之类的东西替换 instanceof Transaction
,但这并没有似乎是可能的。我也考虑过用 instanceof MyEntity
替换它,但这意味着即使两个对象属于不同的 class,只要它们具有相同的 id,也可以认为它们是相等的。
还有其他办法吗?
您可以使用 instanceof
运算符的动态版本,即 Class
的 isInstance
方法。
Determines if the specified Object is assignment-compatible with the object represented by this Class.
if (!(getClass().isInstance(other))) return false;
这不会阻止 subclass 的实例在 superclass 对象上测试 equals
,而是一种确保它完全相同的动态方法 class 将比较两个 Class
对象是否相等。
if (!(getClass().equals(other.getClass()))) return false;
你可以有一个超级 class 和 equals 方法。
// Where ENTITY would be the type of the class to compare, and ID the type of the id
public abstract class ComparableById<ENTITY extends ComparableById, ID> {
protected abstract Class<?> getEntityClass();
protected abstract ID getId();
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!getEntityClass().isInstance(other)) return false;
ComparableById o = (ComparableById) other;
if (getId() == null || o.getId() == null) return false;
return getId().equals(o.getId());
}
}
然后你可以用这种方式在你的所有 class 中使用它:
@Entity
public class TeacherEntity extends ComparablebyId<TeacherEntity, Long> {
private Long id;
@Override
public Long getId() {
return this.id;
}
@Override
public getEntityClass() {
return this.getClass();
}
}
好处:
+ 避免每个 classes.
中的代码重复
+ 支持所有类型。
+ 没有更多演员。
缺点:
- 您需要为每个 class.
getId()
和 getEntityClass()
方法
我喜欢 rgetmann 的回答
boolean equals(Object b){
return getClass().equals(b.getClass())
&& id==getClass().cast(b).id;
}