Ich denke daran, eine reflektive Hilfsmethode für equals und hashCode zu erstellen.Generische reflektive Hilfsmethode für equals und hashCode
Die gute Sache ist, dass ich keine Sorge über fehlende Felder in meiner Equals oder HashCode-Implementierung habe. Das Schlimme ist, denke ich, Leistung. Was denkst du über diese Idee? Bitte teilen Sie Ihre Meinung!
Dies ist mein erster Entwurf für equals:
public final class ReflectiveEqualsHelper {
public static boolean isEqual(final Object a, final Object b) {
if (!isTypeEqual(a, b)) {
return false;
}
Field[] fields = getFields(a);
Object valueA;
Object valueB;
String fieldName;
for (int i = 0; i < fields.length; i++) {
fieldName = fields[i].getName();
valueA = getValueByFieldName(a, fieldName);
valueB = getValueByFieldName(b, fieldName);
if (!compare(valueA, valueB)) {
return false;
}
}
return true;
}
@SuppressWarnings("rawtypes")
private static Field[] getFields(final Object o) {
Class clazz = o.getClass();
Field[] fields = clazz.getDeclaredFields();
return fields;
}
private static Field getField(final Object o, final String name) {
try {
Field field = o.getClass().getDeclaredField(name);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
private static Object getValueByFieldName(final Object o, final String name) {
Field field = getField(o, name);
field.setAccessible(true);
try {
Object value = field.get(o);
field.setAccessible(false);
return value;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private static boolean areBothNull(final Object a, final Object b) {
return (a == null && b == null);
}
private static boolean isTypeEqual(final Object a, final Object b) {
if (areBothNull(a, b)) {
return false;
}
return a.getClass().equals(b.getClass());
}
private static boolean compare(final Object a, final Object b) {
if (a == null) {
return false;
} else if (b == null) {
return false;
}
return a.equals(b);
}
}
public class ReflectiveEqualsHelperTest {
@Test
public void testIsEqual() {
Vector a = new Vector(Long.valueOf(1L), 3L);
Vector b = new Vector(Long.valueOf(1L), 3L);
Vector c = new Vector(Long.valueOf(2L), 3L);
boolean testA = ReflectiveEqualsHelper.isEqual(a, b);
boolean testB = ReflectiveEqualsHelper.isEqual(a, c);
boolean testC = ReflectiveEqualsHelper.isEqual(b, c);
assertTrue(testA);
assertFalse(testB);
assertFalse(testC);
}
class Vector {
public static final int STATIC = 1;
private Long x;
private long y;
public Vector(Long x, long y) {
super();
this.x = x;
this.y = y;
}
public Long getX() {
return x;
}
public void setX(Long x) {
this.x = x;
}
public long getY() {
return y;
}
public void setY(long y) {
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((x == null) ? 0 : x.hashCode());
result = prime * result + (int) (y^(y >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
return ReflectiveEqualsHelper.isEqual(this, obj);
}
}
}
Cheers, Kevin
Ich mache das mit der Sonnenfinsternis und es funktioniert gut für mich Ich habe nur über flexiblere Weise nachgedacht. – eglobetrotter
riesige PITA zu * versuchen * und erinnern Sie sich, diese Methoden jedes Mal wieder zu generieren, wenn Sie ein Feld hinzufügen oder entfernen. mehr als oft nicht, Leute werden vergessen, zu subtilen, schwer zu finden Bugs. Sie haben natürlich Recht mit den Kosten der reflektierenden Lösung. –