java—任何在运行时重写现有对象的方法的简单方法

nqwrtyyt  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(328)

假设我有一个域对象,这里是伪代码

public class SampleClass {
  id
  title
  ... a lot of other fields from database
  public boolean equals(AnotherObj) {
       return this.id.equals(AnotherObj.id);
  }
}

equals方法基于id,这适用于大多数场景。但在一种情况下,如果标题相同,则两个对象应视为相等。对象放在list和list.contains(obj)和list.indexof(obj)中,业务逻辑大量调用它们,这取决于equals方法。
如何在运行时重写equals方法?sampleclass对象可能包含复杂的树子对象,我不想将其复制到内存中。
我想为现有对象创建一个 Package 器。 Package 器仅包含特定的equals方法,所有其他方法调用仍应传递给现有对象。
我查看了cglib,但它必须自己生成目标对象,不能 Package 现有对象。
有什么简单的方法吗?

k4ymrczo

k4ymrczo1#

与其尝试 Package 这些对象,我将修改类,以便它了解在其应用程序中应该检查什么(在每个场景中) equals 方法。在这种特殊情况下,只要设置告诉对象 equals 应该有用。一定不要违反合同。
我还建议实际上 Object#equals (例如,确保 equals 接受 Object ,不仅仅是 AnotherObj ). (当然,像往常一样 hashCode 也是。)
但如果你真的想这么做,你想用 equals ,这听起来像是facade模式的工作在java中有点麻烦:您必须创建另一个完整的类,该类接受对象作为构造函数中的参数,实现除 equals 通过在对象上调用它们,然后(当然)实现 equals 不一样。
所以基本上:

class SampleSubclass extends SampleClass {
    SampleClass inst;

    SampleSubclass(SampleClass inst) {
        this.inst = inst;
    }

    @override
    String someMethod() {
        return inst.someMethod();
    }

    // ...and so on...

    @override
    public boolean equals(AnotherObj other) { // <== But this really should accept Object, not AnotherObj
        // ... implementation...
    }
}
g6baxovj

g6baxovj2#

假设你说的是 Object.equals() / .hashCode() ,这不是您的代码当前所做的,您可以使用guava的 Equivalence .
创建等价项:

public final class SampleClassIdEquivalence
    extends Equivalence<SampleClass>
{
    // override .doEquivalent(), .doHash()
}

然后你可以这样使用它:

final Equivalence<SampleClass> byId = new SampleClassIdEquivalence();

byId.equivalent(o1, o2);

Set<Equivalence.Wrapper<SampleClass>> set = ...

set.add(byId.wrap(whatever));

然后,您可以创建其他等价物,以便通过名称或其他方式实现相等;你的选择。
事实上, Equivalence 差不多是 .equals() / .hashCode() 什么 Comparator 是到 Comparable .

相关问题