Les inconvénients de la réflexion sont les suivants.
Il existe des applications sophistiquées qui tirent parti de la réflexion, comme les outils d'analyse et les cadres d'injection de dépendances, mais elles s'éloignent de la réflexion à mesure que les inconvénients de la réflexion deviennent évidents. Si vous vous demandez si vous devriez utiliser la réflexion, vous ne devriez probablement pas.
La réflexion est utilisée dans des cas très limités.
De nombreux programmes qui doivent utiliser une classe qui ne peut pas être obtenue au moment de la compilation ont un type et une superclasse appropriés comme type pour placer la classe au moment de la compilation (Item64).
Dans ce cas, nous créons des instances de manière réfléchie et accédons à ces instances créées via des interfaces et des superclasses.
Par exemple, dans le programme suivant, une instance de la sous-classe de `` Set
package tryAny.effectiveJava;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Set;
public class Reflection {
// Reflective instantiation with interface access
public static void main(String[] args) {
// Translate the class name into a Class object
Class<? extends Set<String>> cl = null;
try {
cl = (Class<? extends Set<String>>) // Unchecked cast!
Class.forName(args[0]);
} catch (ClassNotFoundException e) {
fatalError("Class not found.");
}
// Get the constructor
Constructor<? extends Set<String>> cons = null;
try {
cons = cl.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
fatalError("No parameterless constructor");
}
// Instantiate the set
Set<String> s = null;
try {
s = cons.newInstance();
} catch (IllegalAccessException e) {
fatalError("Constructor not accessible");
} catch (InstantiationException e) {
fatalError("Class not instantiable.");
} catch (InvocationTargetException e) {
fatalError("Constructor threw " + e.getCause());
} catch (ClassCastException e) {
fatalError("Class doesn't implement Set");
}
// Exercise the set
s.addAll(Arrays.asList(args).subList(1, args.length));
System.out.println(s);
}
private static void fatalError(String msg) {
System.err.println(msg);
System.exit(1);
}
}
La technique utilisée ci-dessus est suffisamment puissante pour être utilisée dans un cadre de fournisseur de services à part entière (? Item1). Cette technique est presque tout ce dont vous avez besoin pour la réflexion.
Ce qui précède présente deux inconvénients.
Dans le code ci-dessus, il y a un avertissement lors de la diffusion.
Cet avertissement est valide car le transtypage en Class <? Extends Set <String >>
`` réussira même si le nom pris comme premier argument n'est pas la classe d'implémentation de Set.
Voir le point 27 pour la suppression des avertissements.
Un cas très rare d'utilisation de la réflexion est l'utilisation dynamique de plusieurs versions d'un package. Compilez la version la plus ancienne et appelez dynamiquement la méthode de la nouvelle classe. (Ça ne vient pas du tout)
Recommended Posts