Java可以帮助我避免equals()中的样板代码吗?
我实现了Java 7方式的equals():
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MyClass other = (MyClass) obj; return Objects.equal(myFirstField, other.myFirstField) && Objects.equal(mySecondField, other.mySecondField); }
有没有办法减少代码重复?
我更喜欢类似的东西
@Override public boolean equals(Object obj) { if (Objects.equalsEarlyExit(this, obj)) return Objects.equalstEarlyExitResult(this, obj); MyClass other = (MyClass) obj; return Objects.equal(myFirstField, other.myFirstField) && Objects.equal(mySecondField, other.mySecondField); }
或类似的。
具有自动装箱和对象创建效率低下的标准API Java:
import static java.util.Arrays.*; import java.util.List; class BrevityBeforeEfficiency { int foo; Object bar; boolean baz; @Override public boolean equals(Object obj) { return (obj instanceof BrevityBeforeEfficiency) && ((BrevityBeforeEfficiency) obj).values().equals(values()); } @Override public int hashCode() { return values().hashCode(); } private List> values() { return asList(foo, bar, baz); } }
你可以使用commons-lang的org.apache.commons.lang.builder.EqualsBuilder
例:
public boolean equals(Object other) { return org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals(this, other); }
其他例子:
private boolean equalsHelper(Object obj) { if (obj == null) return false; if (getClass() != obj.getClass()) return false; return true; } public boolean equals(Object obj) { if (this == obj) return true; if(!equalsHelper(ob)) { return false; } MyClass other = (MyClass) obj; return new EqualsBuilder() .append(myFirstField, other.myFirstField) .append(mySecondField, other.mySecondField).isEquals() }
混合一点inheritance:
public abstract class BusinessObject { protected abstract Object[] getBusinessKeys(); @Override public int hashCode() { return Objects.hash(getBusinessKeys()); } @Override public boolean equals(Object obj) { if(obj == null) return false; if(obj == this) return true; if(obj.getClass() != getClass()) return false; BusinessObject other = (BusinessObject) obj; return Arrays.deepEquals(this.getBusinessKeys(), other.getBusinessKeys()); } }
所以唯一的样板代码是扩展BusinessObject
和单行的getBusinessKeys()
:
public class Node extends BusinessObject { private final String code; private final String name; public Node(String code, String name) { this.code = code; this.name = name; } @Override protected Object[] getBusinessKeys() { return new Object[] { code, name }; } }
这是我能想到的最简单,最干净的:)
这可能是一个实现:
public abstract class EqualsHelper { @SuppressWarnings("unchecked") public static boolean equals(U that, Object other, EqualsHelper equalsHelper) { return that == other || other != null && that.getClass().equals(other.getClass()) && equalsHelper.equals(that, (U) other); } public abstract boolean equals(T that, T other); }
然后:
@Override public boolean equals(Object obj) { return EqualsHelper.equals(this, obj, new EqualsHelper() { @Override public boolean equals(MyClass that, MyClass other) { return Objects.equal(that.myFirstField, other.myFirstField) && Objects.equal(that.mySecondField, other.mySecondField); } }); }
我想知道这是否可以被视为一种反模式 ,所以如果你认为它实际上是毫不犹豫地责备我;)