Réflexion · ch. 11, p. 85
L'API de réflexion
La réflexion inspecte et invoque des types découverts à l'exécution. Elle propulse chaque framework que vous utilisez, et elle vous coûte la sécurité à la compilation, la performance, et la facilité de refactoring.
Class<?> type = Class.forName("com.example.Service");
Object instance = type.getDeclaredConstructor().newInstance();
Method m = type.getDeclaredMethod("execute", String.class);
m.setAccessible(true);
Object result = m.invoke(instance, "payload");
getX vs getDeclaredX
getMethods() renvoie les membres publics, y compris hérités.
getDeclaredMethods() renvoie tout ce qui est déclaré sur cette classe
exacte, y compris privé, mais rien d’hérité. Confondre les deux est le bug de
réflexion le plus courant.
Coûts
- Rien n’est vérifié avant l’exécution ; un renommage le casse silencieusement.
invokeemballe les arguments dans unObject[]et enveloppe toute exception lancée dansInvocationTargetException— toujours déballer avecgetCause().- Les appels réflexifs résistent à l’inlining, bien que le JIT moderne réduise l’écart.
- Depuis Java 9,
setAccessiblesur les internes d’un autre module est refusé sauf si ce module ouvre le package. C’est pourquoi d’anciennes bibliothèques ont cassé sur 9+.
Relire les génériques
L’effacement retire les arguments de type des valeurs mais conserve les signatures dans le fichier de classe, donc les types déclarés restent lisibles :
Type t = field.getGenericType();
if (t instanceof ParameterizedType pt) {
Type arg = pt.getActualTypeArguments()[0]; // par ex. String
} 2 questions sur ce concept S'entraîner