在不知道类型

时间:2016-02-08 22:29:25

标签: java instanceof dynamic-typing

我的Java类代表数据库中的实体,我发现覆盖我的类的equals方法以通过id进行比较是切实可行的。例如,在我的Transaction课程中,我有这段代码

@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);
}

现在看起来有点难看,每个类都拥有相同的代码片段,只更改了类的名称。我考虑过让我的类扩展一个超类MyEntity,我会写上面的方法,用instanceof Transaction替换instanceof this.getClass(),但这似乎不可能。我还考虑用instanceof MyEntity替换它,但这意味着即使它们属于不同的类,只要它们具有相同的id,两个对象也可以被认为是相等的。 还有其他办法吗?

3 个答案:

答案 0 :(得分:6)

您可以使用instanceof运算符的动态版本,即Class的{​​{1}}方法。

  

确定指定的Object是否与此Class表示的对象分配兼容。

isInstance

这不会阻止子类的实例在超类对象上测试if (!(getClass().isInstance(other))) return false; ,但是确保它是完全相同的类的动态方法是比较两个equals对象的相等性

Class

答案 1 :(得分:1)

你可以使用等于方法的超类。

// 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());
    }

}

然后你可以用这种方式在你的所有课堂上使用它:

@Entity
public class TeacherEntity extends ComparablebyId<TeacherEntity, Long> {
    private Long id;

    @Override
    public Long getId() {
        return this.id;
    }

    @Override
    public getEntityClass() {
        return this.getClass();
    }
}

好处:
 +您可以避免每个类中的代码重复  +所有类型都被支持。
 +没有更多演员。

缺点:
  - 您需要为每个班级定义getId()getEntityClass()方法。

答案 2 :(得分:1)

我喜欢rgetmann的回答https://stackoverflow.com/a/35280674/348975,但它不完整。我认为以下代码(不以任何方式测试)完成它。

0