Desvantagens da reflexão em geral
A reflexão é mais difícil de entender do que o código linear.
Na minha experiência, a reflexão é um recurso de "nível de especialista" em Java. Eu diria que a maioria dos programadores nunca usa reflexão ativamente (ou seja, consumir bibliotecas que usam reflexão não conta). Isso torna o código mais difícil de entender para esses programadores.
Código de reflexão inacessível à análise estática
Suponha que eu tenha um getter getFoo
na minha classe e queira renomeá-lo para getBar
. Se eu não usar reflexão, basta pesquisar na base de código getFoo
e encontrar todos os locais que usam o getter para que eu possa atualizá-la, e mesmo que eu perca uma, o compilador reclamará.
Mas se o local que usa o getter é algo como callGetter("Foo")
e o callGetter
faz getClass().getMethod("get"+name).invoke(this)
, então o método acima não o encontrará e o compilador não irá reclamar. Somente quando o código for realmente executado, você obterá um NoSuchMethodException
. E imagine a dor que você sente se essa exceção (que é rastreada) é engolida callGetter
porque "é usada apenas com cadeias codificadas, não pode realmente acontecer". (Ninguém faria isso, alguém poderia argumentar? Exceto que o OP fez exatamente isso em sua resposta ao SO. Se o campo fosse renomeado, os usuários do setter genérico nunca perceberiam, exceto o bug extremamente obscuro do setter silenciosamente, sem fazer nada. Os usuários do getter podem, se tiverem sorte, perceber a saída do console da exceção ignorada.)
O código de reflexão não é verificado pelo tipo pelo compilador
Este é basicamente um grande sub-ponto do exposto acima. Código de reflexão é tudo Object
. Os tipos são verificados em tempo de execução. Os erros são descobertos por testes de unidade, mas apenas se você tiver cobertura. ("É apenas um getter, não preciso testá-lo.") Basicamente, você perde a vantagem de usar o Java sobre o Python, que ganhou em primeiro lugar.
O código de reflexão não está disponível para otimização
Talvez não na teoria, mas na prática, você não encontrará uma JVM que inclua ou crie um cache embutido Method.invoke
. As chamadas de método normal estão disponíveis para essas otimizações. Isso os torna muito mais rápidos.
Código de reflexão é apenas lento em geral
A pesquisa de método dinâmico e a verificação de tipo necessárias para o código de reflexão são mais lentas que as chamadas de método normais. Se você transformar esse dispositivo barato de uma linha em um animal de reflexão, poderá (eu não medi isso) observar várias ordens de magnitude de desaceleração.
Desvantagem do getter / setter genérico especificamente
Essa é apenas uma péssima idéia, porque sua classe agora não tem mais encapsulamento. Todos os campos que ele possui são acessíveis. Você também pode torná-los públicos.