제이온

[Java] Conceito e Uso de Reflection

  • Idioma de escrita: Coreana
  • País de referência: Todos os paísescountry-flag
  • TI

Criado: 2024-04-25

Criado: 2024-04-25 22:27

O que é Reflexão?

Reflexão é uma API que permite criar instâncias de uma classe desejada por meio de um objeto do tipo Class carregado na área de heap e acessar os campos e métodos dessa instância, independentemente dos modificadores de acesso.



Aqui, a classe carregada se refere ao carregamento do arquivo de classe pelo carregador de classe do JVM e, em seguida, à criação de um objeto do tipo Classque contém as informações da classe e o armazena na área de heap da memória. Observe que isso é diferente dos objetos criados com a palavra-chave new. Se você não entender bem o objeto do tipo Class, consulte a documentação do JDK para java.lang.class.


Como usar

Antes de usar a reflexão, você precisa obter o objeto do tipo Class carregado na área de heap. Existem três maneiras de fazer isso.


  • Obter com Classe.class
  • Obter com Instância.getClass()
  • Obter com Class.forName("NomeDaClasse")


Podemos ver que as instâncias do tipo Class obtidas pelos três métodos são as mesmas. O valor hash é o mesmo, independentemente do método usado, então você pode usá-lo de acordo com a situação.


Agora que temos o objeto do tipo Class, podemos criar uma instância da classe e acessar os campos e métodos da instância, independentemente dos modificadores de acesso. Primeiro, vamos criar uma instância da classe.


Podemos obter o construtor usando getConstructor() e criar dinamicamente uma instância de Member usando newInstance().

Finalmente, vamos acessar e usar os campos e métodos da instância, independentemente dos modificadores de acesso.

Podemos obter todas as variáveis de instância da classe usando getDeclaredFileds() e retornar o valor do campo usando get() e modificar o valor do campo usando set(). Observe que, ao acessar um campo com o modificador de acesso private, você precisa definir o parâmetro de setAccessible() como true.


Da mesma forma, podemos obter o método usando getDeclaredMethod(). Nesse caso, precisamos passar o nome do método e o tipo do parâmetro como parâmetros. Da mesma forma, ao acessar um método com o modificador de acesso private, você precisa definir o parâmetro de setAccessible() como true. Finalmente, podemos chamar o método obtido pela API de reflexão usando o método invoke().


Prós e Contras

  • Vantagens
    • Tem flexibilidade para realizar as tarefas necessárias acessando campos e métodos de uma classe, independentemente dos modificadores de acesso, criando instâncias de classes em tempo de execução.
  • Desvantagens
    • Viola o encapsulamento.
    • Como as instâncias são criadas em tempo de execução, o tipo não pode ser verificado em tempo de compilação.
    • Como as instâncias são criadas em tempo de execução, é difícil entender o fluxo de execução específico.
    • O desempenho é mais lento do que acessar campos e métodos diretamente, em comparação com o acesso por meio da API de reflexão. (Não é sempre mais lento.)


Razões para usar

Por meio da API de reflexão, podemos acessar as informações da classe em tempo de execução e manipular a classe como quisermos. Podemos até mesmo manipular campos e métodos declarados com o modificador de acesso private. Isso pode parecer uma tecnologia que não deve ser usada porque viola o encapsulamento, um conceito importante na programação orientada a objetos.


Em um ambiente de console pequeno, o desenvolvedor pode entender completamente os objetos e suas relações de dependência que serão usados no programa em tempo de compilação. No entanto, em um ambiente de desenvolvimento de grande escala, como um framework, é difícil entender os muitos objetos e suas relações de dependência. Nesse caso, a reflexão pode ser usada para criar classes dinamicamente e estabelecer relações de dependência.


Por exemplo, no Bean Factory do Spring, podemos ver que, se adicionarmos anotações como @Controller, @Service e @Repository, o Bean Factory criará e gerenciará automaticamente as classes com essas anotações. Embora o desenvolvedor não tenha informado ao Bean Factory sobre essas classes, isso é possível graças à reflexão. Em tempo de execução, ele pesquisa e encontra as classes com essas anotações e, se encontradas, cria instâncias dessas classes por meio da reflexão, injeta os campos necessários e as salva no Bean Factory.


Claro, como mencionado acima, a reflexão viola o encapsulamento, portanto, é melhor usá-la apenas quando necessário.


Fontes

Comentários0