Refleksja — to mechanizm umożliwiający badanie i modyfikację struktury oraz zachowania klas, obiektów, metod i pól w trakcie wykonywania programu. Jest realizowana przez pakiet java.lang.reflect.
Pozwala na:
Przykład:
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); // Wyświetli: Hello! } }
Zalety:
Wady/ryzyko:
Czy można uzyskać dostęp do pól i metod klasy oznaczonych jako private za pomocą refleksji i jakie są tego konsekwencje?
Odpowiedź: Tak, jest to możliwe za pomocą metody setAccessible(true) w Field lub Method:
Field field = clazz.getDeclaredField("privateField"); field.setAccessible(true); field.set(obj, "value");
To narusza inkapsulację klasy i wiąże się z ryzykiem: sytuacja staje się krucha, możliwe są błędy związane z bezpieczeństwem, a w nowych wersjach JVM takie działania mogą być ograniczone polityką dostępu.
Historia
W dużym projekcie do automatycznego mapowania DTO przez refleksję pola o typie "Optional" nie były prawidłowo uwzględniane, co prowadziło do NullPointerException podczas masowego przetwarzania danych, ponieważ pakiet refleksji nie rozróżniał wartości Optional i null.
Historia
W oprogramowaniu bankowym wdrożono dostęp do prywatnych pól przez setAccessible(true) do serializacji. Po aktualizacji JVM zachowanie się zmieniło, dostęp do prywatnego pola okazał się zablokowany, a ważna funkcjonalność serializacji nagle przestała działać w produkcji.
Historia
W frameworku ORM podczas generowania obiektów proxy zapomniano odświeżyć pamięć podręczną refleksji po zmianie schematu danych. W efekcie system generował nieprzewidywalne wyjątki podczas pracy z nowymi polami klas, które nie były odzwierciedlone w pamięci podręcznej.