Reflexão em Java (java.lang.reflect):
Através da reflexão, é possível:
- Acessar programaticamente construtores, métodos e campos de classes arbitrárias.
- Manipular classes e seus membros (construtores, métodos, campos) de maneira reflexiva, permitindo criar instâncias, invocar métodos e acessar campos.
- Invocar métodos em objetos, mesmo que as classes não existam durante a compilação.
Desvantagens da Reflexão:
Perda de verificação de tipo em tempo de compilação:
- Erros que normalmente seriam detectados na compilação só aparecerão em tempo de execução.
- Exemplo: invocar reflexivamente um método inexistente ou inacessível pode gerar exceções em tempo de execução.
Código pesado e verboso:
Reflexão exige código mais complexo e menos legível.
Exemplo:
Method method = obj.getClass().getMethod("methodName");
method.invoke(obj, args);
Desempenho inferior:
- Invocação reflexiva de métodos é consideravelmente mais lenta do que a invocação normal.
- Exemplo: em certos cenários, a reflexão pode ser até 11 vezes mais lenta que a invocação direta de métodos.
Aplicações da Reflexão:
- Usada em ferramentas de análise de código, frameworks de injeção de dependências e service provider frameworks.
- Mesmo nesses contextos, deve ser evitada quando possível devido às suas desvantagens.
Uso limitado da reflexão:
Técnica sugerida: use reflexão apenas para instanciar classes desconhecidas em tempo de compilação e referencie essas instâncias por meio de interfaces ou superclasses conhecidas.
Exemplo:
Programa que cria instâncias de Set, especificadas pela linha de comando:
Class<? extends Set<String>> cl = (Class<? extends Set<String>>) Class.forName(args[0]);
Constructor<? extends Set<String>> cons = cl.getDeclaredConstructor();
Set<String> s = cons.newInstance();
for (int i = 1; i < args.length; i++) {
s.add(args[i]);
}
System.out.println(s);
Desvantagens ilustradas no exemplo:
Exceções de tempo de execução:
- O exemplo pode gerar até seis exceções diferentes em tempo de execução.
- Essas exceções seriam capturadas em tempo de compilação se não fosse usada a reflexão.
Complexidade e verbosidade:
- O exemplo requer 25 linhas de código para instanciar uma classe a partir de seu nome, enquanto uma chamada de construtor direta seria feita em apenas uma linha.
Advertência de cast não verificado:
- No exemplo, há uma advertência legítima de cast não verificado, pois a classe especificada na linha de comando pode não ser uma implementação de Set.
Uso legítimo da reflexão:
- Dependências dinâmicas: quando uma classe, método ou campo pode não existir em tempo de execução.
- Exemplo: você pode usar reflexão para suportar múltiplas versões de um pacote sem quebrar a compatibilidade com versões anteriores.
Conclusão:
Reflexão é poderosa, mas apresenta muitas desvantagens.
Sempre que possível, use a reflexão apenas para instanciar objetos e acesse-os por meio de interfaces ou superclasses conhecidas em tempo de compilação.
Top comments (0)