Warum ist class.newInstance () „böse“?
-
10-07-2019 - |
Lösung
Die Java-API-Dokumentation erklärt, warum ( http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance () ):
Beachten Sie, dass diese Methode jede Ausnahme von dem nullary Konstruktor, darunter eine geprüfte Ausnahme geworfen ausbreitet. Die Verwendung dieses Verfahrens umgeht effektiv die Kompilierung-Ausnahmenüberprüfung, die ansonsten durch den Compiler durchgeführt werden würde. Das
Constructor.newInstance
Verfahren vermeidet dieses Problem durch die Ausnahme vom Konstruktor in einem (überprüft)InvocationTargetException
geworfen gewickelt wird.
Mit anderen Worten, es kann das geprüfte Ausnahmen System besiegen.
Andere Tipps
Ein weiterer Grund:
Moderne IDEs können Sie Klasse Nutzungen finden -. Es während Refactoring hilft, wenn Sie und Ihre IDE wissen, welche Codes verwenden Klasse, die Sie ändern wollen
Wenn Sie keine explizite Verwendung des Konstruktor tun, sondern verwenden class.newInstance () statt, riskieren Sie nicht, dass die Nutzung während Refactoring zu finden und dieses Problem wird sich nicht manifestieren, wenn Sie kompilieren.
Ich weiß nicht, warum niemand ein einfaches Beispiel zur Verfügung gestellt Basis Erklärung dazu im Vergleich zu Constructor::newInstance
zum Beispiel, da schließlich Class::newInstance
seit java-9 aufgegeben.
Angenommen, Sie diese sehr einfache Klasse hat (spielt keine Rolle, dass es kaputt ist):
static class Foo {
public Foo() throws IOException {
throw new IOException();
}
}
Und Sie versuchen, eine Instanz davon über Reflexion zu schaffen. Erste Class::newInstance
:
Class<Foo> clazz = ...
try {
clazz.newInstance();
} catch (InstantiationException e) {
// handle 1
} catch (IllegalAccessException e) {
// handle 2
}
Diesen Aufruf in einem IOException
führen wird geworfen -. Problem ist, dass Ihr Code ist es nicht handhaben, weder handle 1
noch handle 2
wird es fangen
Im Gegensatz, wenn es über eine Constructor
tun:
Constructor<Foo> constructor = null;
try {
constructor = clazz.getConstructor();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
Foo foo = constructor.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println("handle 3 called");
e.printStackTrace();
}
, die 3 behandelt genannt werden, so werden Sie damit umgehen.
Effektiv Class::newInstance
umgeht die Ausnahmebehandlung - die Sie wirklich nicht wollen,