La réflexion est un mécanisme permettant d'explorer et de modifier la structure et le comportement des classes, objets, méthodes et champs à l'exécution du programme. Elle est réalisée via le package java.lang.reflect.
Elle permet de :
Exemple :
import java.lang.reflect.Method; public class ReflectionExample { public void greet() { System.out.println("Hello!"); } public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("ReflectionExample"); Object instance = clazz.getDeclaredConstructor().newInstance(); Method method = clazz.getMethod("greet"); method.invoke(instance); // Affichera: Hello! } }
Avantages:
Inconvénients/risques :
Peut-on accéder aux champs et méthodes privées d'une classe via la réflexion, et quelles en sont les conséquences ?
Réponse : Oui, c'est possible grâce à la méthode setAccessible(true) sur Field ou Method :
Field field = clazz.getDeclaredField("privateField"); field.setAccessible(true); field.set(obj, "value");
Cela viole l'encapsulation de la classe et présente des risques : la situation devient fragile, des erreurs de sécurité peuvent survenir, et dans les nouvelles versions de la JVM, ces actions peuvent être limitées par des politiques d'accès.
Histoire
Dans un grand projet pour le mappage automatique des DTO via la réflexion, les champs de type "Optional" n'étaient pas correctement pris en compte, ce qui entraînait des NullPointerException lors de traitements de données en masse, car le package de réflexion ne distinguait pas les valeurs Optional et null.
Histoire
Dans un logiciel bancaire, un accès aux champs privés a été réalisé via setAccessible(true) pour la sérialisation. Après une mise à jour de la JVM, le comportement a changé, l'accès au champ privé s'est retrouvé bloqué, une fonctionnalité essentielle de sérialisation a soudainement cessé de fonctionner en production.
Histoire
Dans un framework ORM, lors de la génération d'objets proxy, on a oublié de rafraîchir le cache de réflexion après avoir modifié le schéma des données. En conséquence, le système renvoyait des exceptions imprévisibles lors de l'utilisation de nouveaux champs de classes qui n'étaient pas reflétés dans le cache.