Desvantagens da reflexão em geral
A reflexão é mais difícil de entender do que o código em linha reta.
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 a reflexão ativamente (ou seja, o consumo de bibliotecas que usam reflexão não conta). Isso torna o código mais difícil de entender para esses programadores.
O código de reflexão está inacessível à análise estática
Suponha que eu tenha um getter getFoo
em minha classe e quero renomeá-lo para getBar
. Se eu não usar nenhum reflexo, posso apenas pesquisar a base de código para getFoo
e encontrarei todos os locais que usam o getter para que eu possa atualizá-lo, e mesmo se eu perder um, o compilador irá reclamar.
Mas se o lugar que usa o getter for algo como callGetter("Foo")
e callGetter
faz getClass().getMethod("get"+name).invoke(this)
, o método acima não o encontrará e o compilador não se queixará. Somente quando o código for realmente executado, você obterá um NoSuchMethodException
. E imagine a dor em que você está se essa exceção (que é rastreada) for engolida por callGetter
porque "ela é usada apenas com strings codificadas, não pode acontecer de fato". (Ninguém faria isso, alguém poderia argumentar? Exceto que o OP fez exatamente isso em sua resposta SO. Se o campo for renomeado, os usuários do genérico nunca perceberiam, exceto pelo bug extremamente obscuro do setter silenciosamente não fazendo nada. 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 compilador
Este é basicamente um grande sub-ponto do que foi dito acima. O código de reflexão é sobre Object
. Os tipos são verificados no tempo de execução. Erros são descobertos por testes de unidade, mas somente se você tiver cobertura. ("É apenas um getter, eu não preciso testá-lo.") Basicamente, você perde a vantagem usando Java sobre Python ganhou em primeiro lugar.
O código de reflexão não está disponível para otimização
Talvez não em teoria, mas, na prática, você não encontrará uma JVM que insira ou crie um cache in-line para Method.invoke
. Chamadas de método normais estão disponíveis para essas otimizações. Isso os torna muito mais rápidos.
O código de reflexão é 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 aquele getter barato de uma linha em um animal de reflexão, você pode (eu não medi isso) estar olhando para várias ordens de magnitude de desaceleração.
Desvantagem do getter / setter genérico especificamente
Isso é apenas uma má ideia, porque sua classe agora não tem mais encapsulamento. O campo Every que ele possui está acessível. Você também pode torná-los públicos.