Ist es eine gute Praxis, Reflektion zu verwenden, wenn die Anzahl der Kesselschild-Codes stark reduziert wird?
Grundsätzlich gibt es einen Kompromiss zwischen Leistung und Lesbarkeit auf der einen Seite und Abstraktion / Automatisierung / Reduzierung von Code auf der anderen Seite.
Bearbeiten: Hier ist ein Beispiel für eine empfohlene Verwendung der Reflexion .
Um ein Beispiel zu geben : Angenommen , es gibt eine eine abstrakte Klasse , Base
die 10 Felder hat und hat drei Unterklassen SubclassA
, SubclassB
und SubclassC
jeweils mit 10 verschiedenen Bereichen; es sind alles einfache Bohnen. Das Problem ist, dass Sie zwei Base
Typreferenzen erhalten und sehen möchten, ob die entsprechenden Objekte vom gleichen (Unter-) Typ und gleich sind.
Als Lösungen gibt es die unformatierte Lösung, bei der Sie zuerst prüfen, ob die Typen gleich sind, und dann alle Felder prüfen, oder Sie können Reflection verwenden und dynamisch feststellen, ob sie vom gleichen Typ sind, und alle Methoden durchlaufen, die mit "get" (Konvention) beginnen über Konfiguration), rufen Sie sie für beide Objekte auf und rufen Sie gleich für die Ergebnisse auf.
boolean compare(Base base1, Base, base2) {
if (base1 instanceof SubclassA && base2 instanceof SubclassA) {
SubclassA subclassA1 = (SubclassA) base1;
SubclassA subclassA2 = (SubclassA) base2;
compare(subclassA1, subclassA2);
} else if (base1 instanceof SubclassB && base2 instanceof SubclassB) {
//the same
}
//boilerplate
}
boolean compare(SubclassA subA1, SubclassA subA2) {
if (!subA1.getField1().equals(subA2.getField1)) {
return false;
}
if (!subA1.getField2().equals(subA2.getField2)) {
return false;
}
//boilerplate
}
boolean compare(SubclassB subB1, SubclassB subB2) {
//boilerplate
}
//boilerplate
//alternative with reflection
boolean compare(Base base1, Base base2) {
if (!base1.getClass().isAssignableFrom(base2.getClass())) {
System.out.println("not same");
System.exit(1);
}
Method[] methods = base1.getClass().getMethods();
boolean isOk = true;
for (Method method : methods) {
final String methodName = method.getName();
if (methodName.startsWith("get")) {
Object object1 = method.invoke(base1);
Object object2 = method.invoke(base2);
if(object1 == null || object2 == null) {
continue;
}
if (!object1.equals(object2)) {
System.out.println("not equals because " + object1 + " not equal with " + object2);
isOk = false;
}
}
}
if (isOk) {
System.out.println("is OK");
}
}