Desventajas de la reflexión en general
La reflexión es más difícil de entender que el código de línea recta.
En mi experiencia, la reflexión es una función de "nivel experto" en Java. Yo diría que la mayoría de los programadores nunca usan la reflexión activamente (es decir, el consumo de bibliotecas que usan la reflexión no cuenta). Eso hace que el código sea más difícil de entender para estos programadores.
El código de reflexión es inaccesible para el análisis estático
Supongamos que tengo un getter getFoo
en mi clase y quiero cambiarle el nombre a getBar
. Si no uso ningún reflejo, solo puedo buscar en el código base para getFoo
y encontraré cada lugar que use el getter para poder actualizarlo, e incluso si pierdo uno, el compilador se quejará.
Pero si el lugar que utiliza el captador es algo como callGetter("Foo")
y callGetter
hace getClass().getMethod("get"+name).invoke(this)
, entonces el método anterior no lo encontrará y el compilador no se quejará. Solo cuando el código se ejecute realmente obtendrá un NoSuchMethodException
. E imagine el dolor en el que se encuentra si esa excepción (que se rastrea) es tragada por callGetter
porque "solo se usa con cadenas codificadas, no puede suceder". (¿Nadie haría eso? ¿Alguien podría discutir? Excepto que el OP hizo exactamente eso en su respuesta SO. Si se cambia el nombre del campo, los usuarios del genérico nunca lo notarán, excepto por el error extremadamente oscuro El setter no hace nada en silencio. Los usuarios del getter pueden, si tienen suerte, notar la salida de la consola de la excepción ignorada.)
El compilador no comprueba el código de reflexión
Esto es básicamente un gran subpunto de lo anterior. El código de reflexión tiene que ver con Object
. Los tipos se verifican en tiempo de ejecución. Los errores se descubren mediante pruebas unitarias, pero solo si tiene cobertura. ("Es solo un captador, no necesito probarlo"). Básicamente, pierdes la ventaja de que Java sobre Python te ganó en primer lugar.
El código de reflexión no está disponible para optimización
Tal vez no en teoría, pero en la práctica, no encontrará una JVM que incluya o cree un caché en línea para Method.invoke
. Las llamadas a métodos normales están disponibles para tales optimizaciones. Eso los hace mucho más rápidos.
El código de reflexión es lento en general
La búsqueda dinámica de métodos y la verificación de tipos necesaria para el código de reflexión es más lenta que las llamadas de métodos normales. Si convierte ese captador barato de una línea en una bestia de reflexión, podría (no he medido esto) estar observando varios órdenes de magnitud de desaceleración.
La desventaja de un genérico getter / setter específicamente
Eso es simplemente una mala idea, porque tu clase ya no tiene encapsulación. Cada campo que tiene es accesible. Podrías también hacerlos públicos.