Inconvénients de la réflexion en général
La réflexion est plus difficile à comprendre que le code en ligne droite.
D'après mon expérience, la réflexion est une fonctionnalité "de niveau expert" en Java. Je dirais que la plupart des programmeurs n’utilisent jamais de réflexion de manière active (c’est-à-dire que les bibliothèques consommatrices de réflexion ne comptent pas). Cela rend le code plus difficile à comprendre pour ces programmeurs.
Le code de réflexion est inaccessible à l'analyse statique
Supposons que j'ai un getter getFoo
dans ma classe et que je veuille le renommer getBar
. Si je n'utilise pas de réflexion, je peux simplement chercher dans la base de code getFoo
et trouver chaque endroit qui utilise le getter afin que je puisse le mettre à jour, et même si j'en manque un, le compilateur se plaindra.
Mais si le lieu qui utilise le getter est quelque chose comme callGetter("Foo")
et callGetter
fait getClass().getMethod("get"+name).invoke(this)
, la méthode ci - dessus ne trouvera pas, et le compilateur ne se plaindra pas. Vous obtiendrez un NoSuchMethodException
. Et imaginez la douleur que vous éprouvez si cette exception (qui est suivie) est avalée callGetter
car "elle est uniquement utilisée avec des chaînes codées en dur, cela ne peut pas réellement arriver". (Personne ne ferait cela, pourrait-on arguer? Sauf que l'OP l'a fait exactement dans sa réponse SO. Si le champ est renommé, les utilisateurs du configurateur générique ne le remarqueront jamais, à l'exception du bogue extrêmement obscur du poseur qui ne fait rien en silence. Les utilisateurs du getter peuvent, s’ils ont de la chance, remarquer la sortie console de l’exception ignorée.)
Le code de réflexion n'est pas vérifié par le compilateur
Ceci est fondamentalement un gros sous-point de ce qui précède. Le code de réflexion est tout au sujet Object
. Les types sont vérifiés à l'exécution. Les erreurs sont découvertes par des tests unitaires, mais uniquement si vous êtes couvert. ("C'est juste un getter, je n'ai pas besoin de le tester.") En gros, vous perdez l'avantage en utilisant Java par rapport à Python.
Le code de réflexion n'est pas disponible pour l'optimisation
Peut-être pas en théorie, mais en pratique, vous ne trouverez pas de machine virtuelle qui installe ou crée un cache en ligne Method.invoke
. Des appels de méthode normaux sont disponibles pour de telles optimisations. Cela les rend beaucoup plus rapide.
Le code de réflexion est simplement lent en général
La recherche de méthode dynamique et la vérification de type nécessaires pour le code de réflexion sont plus lentes que les appels de méthode normaux. Si vous transformez ce getter bon marché sur une ligne en une bête de réflexion, vous risquez (je ne l’ai pas encore mesuré) d’observer un ralentissement de plusieurs ordres de grandeur.
Inconvénient du getter / setter générique en particulier
C'est juste une mauvaise idée, car votre classe n'a plus d'encapsulation. Chaque champ dont il dispose est accessible. Vous pourriez aussi bien les rendre tous publics.