Je l'ai fait parce que je voulais comparer les beans les uns avec les autres dans JUnit.
Correction d'un bug qui provoquait une boucle infinie lorsque la méthode equals était implémentée avec cela.
Quand jette, l'appelant est Mendokusai, donc je l'ai modifié pour attraper en interne.
Pour les classes sous java.lang ⇒ Appelez la méthode native equals. Compare toStrings si la méthode equals n'est pas implémentée
S'il n'est pas sous java.lang et qu'il s'agit d'un tableau ⇒ Vérifiez la longueur et chaque élément
S'il n'est pas sous java.lang et que ce n'est pas un tableau ⇒ Vérifiez la valeur du champ
/**
*Méthode d'égalité pratique
*OK même si la méthode equals n'est pas implémentée.Je vais aussi vérifier le champ super classe.
* @param a
* @param b
* @return
*/
@SuppressWarnings("unchecked")
public static boolean reflectEquals( Object a, Object b ){
try{
if (a == b) {
return true;
}
if (a == null || b == null ) {
return a == b;
}
if (a.getClass() != b.getClass()) {
return false;
}
boolean useBuildinEqualsFlg = a.getClass().getName().startsWith("java.lang");
if( useBuildinEqualsFlg ){
try{
Method equalsMethod = a.getClass().getDeclaredMethod("equals", Object.class);
boolean eqFlg = Boolean.class.cast( equalsMethod.invoke(a, b) );
return eqFlg;
}catch( NoSuchMethodException e ) {
String aStr = a.toString();
String bStr = b.toString();
boolean eqFlg = aStr.equals(bStr);
return eqFlg;
}
}else{
if( a instanceof List ) {
a = ((List<Object>) a).toArray();
b = ((List<Object>) b).toArray();
}
if( a.getClass().isArray() ) {
int aLen = Array.getLength(a);
int bLen = Array.getLength(b);
if( aLen != bLen ) {
return false;
}
for( int i = 0;i<aLen;i++) {
Object aElement= Array.get(a, i);
Object bElement= Array.get(b, i);
if( !reflectEquals( aElement, bElement ) ) {
return false;
}
}
return true;
}
List<Field> fields = getAllFields(a.getClass());
for( Field field : fields ) {
field.setAccessible(true);
Object aFieldObj = field.get(a);
Object bFieldObj = field.get(b);
boolean eqFlg = reflectEquals( aFieldObj, bFieldObj);
if( !eqFlg ) {
return false;
}
}
return true;
}
}catch(IllegalAccessException | IllegalArgumentException | SecurityException | InvocationTargetException e ){
throw new RuntimeException(e);
}
}
/**
*La super classe revient également et obtient tous les champs
* @param clazz
* @return
*/
private static List<Field> getAllFields(Class<?> clazz){
List<Field> allFields = new ArrayList<>();
if( clazz != Object.class ) {
Field[] fields = clazz.getDeclaredFields();
allFields.addAll( Arrays.asList(fields) );
allFields.addAll( getAllFields(clazz.getSuperclass()) );
}
return allFields;
}
↓ Appelez comme ça.
reflectEquals(obj1, obj2)
Après avoir réalisé un chef-d'œuvre, j'ai réalisé que c'était tout ce que j'avais à faire ...
Gson gson = new GsonBuilder().setPrettyPrinting().create();
gson.toJson(obj1).equals( gson.toJson(obj2) );
Recommended Posts