ProgrammazioneSviluppatore Backend

Che cos'è la riflessione (Reflection) in Java? Quali sono i suoi vantaggi, svantaggi e rischi potenziali nell'uso?

Supera i colloqui con l'assistente IA Hintsage

Risposta

Riflessione — è un meccanismo che consente di esplorare e modificare la struttura e il comportamento di classi, oggetti, metodi e campi durante l'esecuzione di un programma. È realizzato tramite il pacchetto java.lang.reflect.

Permette di:

  • Ottenere informazioni sulle classi durante l'esecuzione
  • Chiamare metodi e accedere ai campi dinamicamente
  • Creare nuove istanze di classi per nome

Esempio:

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); // Stampa: Hello! } }

Vantaggi:

  • Flessibilità ed espandibilità (ad esempio, framework, DI)
  • Possibilità di codice generico per operazioni con oggetti, senza conoscere i loro tipi in anticipo

Svantaggi/rischi:

  • Riduzione delle prestazioni
  • Potenziali problemi di sicurezza (bypass dei modificatori di accesso)
  • Rompe l'incapsulamento
  • Minor manutenibilità

Domanda trabocchetto

È possibile accedere ai campi e ai metodi privati di una classe tramite riflessione, e quali sono le conseguenze di ciò?

Risposta: Sì, è possibile tramite il metodo setAccessible(true) di Field o Method:

Field field = clazz.getDeclaredField("privateField"); field.setAccessible(true); field.set(obj, "value");

Questo viola l'incapsulamento della classe e comporta rischi: la situazione diventa fragile, possono sorgere errori di sicurezza, e nelle nuove versioni della JVM tali azioni possono essere limitate dalle politiche di accesso.

Esempi di errori reali dovuti alla mancanza di conoscenza delle sfumature del tema


Storia

In un grande progetto per il mappaggio automatico di DTO tramite riflessione, i campi di tipo "Optional" non venivano gestiti correttamente, portando a NullPointerException durante l'elaborazione di massa dei dati, poiché il pacchetto di riflessione non distingueva i valori Optional e null.


Storia

In un software bancario, è stato implementato l'accesso ai campi privati tramite setAccessible(true) per la serializzazione. Dopo un aggiornamento della JVM, il comportamento è cambiato, l'accesso al campo privato è risultato bloccato, e una funzionalità importante di serializzazione ha improvvisamente smesso di funzionare in produzione.


Storia

In un framework ORM, dimenticai di aggiornare la cache della riflessione dopo aver modificato lo schema dei dati. Di conseguenza, il sistema ha generato eccezioni imprevedibili quando si lavorava con nuovi campi delle classi, che non erano riflessi nella cache.