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 característica 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 uso del 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 captador getFoo
en mi clase y quiero cambiarle el nombre getBar
. Si no utilizo ningún reflejo, simplemente puedo buscar la base del código getFoo
y encontraré todos los lugares que usan el captador para poder actualizarlo, e incluso si me pierdo uno, el compilador se quejará.
Pero si el lugar que usa el captador es algo así callGetter("Foo")
y lo 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 está sufriendo si se traga esa excepción (que se rastrea) callGetter
porque "solo se usa con cadenas codificadas, en realidad 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 setter genérico nunca lo notarían, excepto por el error extremadamente oscuro del setter que no hace nada en silencio. Los usuarios del getter podrían, si tienen suerte, notar la salida de la consola de la excepción ignorada).
El compilador no verifica el código de reflexión
Esto es básicamente un gran subpunto de lo anterior. El código de reflexión se trata 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 usar Java sobre Python que obtuviste en primer lugar.
El código de reflexión no está disponible para la optimización
Tal vez no en teoría, pero en la práctica, no encontrará una JVM que alinee o cree una caché en línea 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 necesarios para el código de reflexión es más lenta que las llamadas a métodos normales. Si convierte ese captador de una línea barato en una bestia reflectante, podría (no he medido esto) estar observando varios órdenes de magnitud de desaceleración.
Desventaja de getter / setter genérico específicamente
Esa es solo una mala idea, porque su clase ahora ya no tiene encapsulación. Cada campo que tiene es accesible. También podrías hacerlos públicos.