Para entender o princípio da reflexão, você deve primeiro entender que tipo de informação é. O Java nos permite identificar as informações de objetos e classes em tempo de execução, e existem duas maneiras principais: uma é a RTTI tradicional, que pressupõe que já conhecemos todas as informações de tipo em tempo de compilação; O outro é o mecanismo de reflexão, que nos permite descobrir e usar as informações das classes em tempo de execução .
1. Objeto de classe
Para entender como o RTTI funciona em Java, você precisa primeiro saber como as informações do tipo são representadas em tempo de execução. Isso é feito pelos objetos de classe, que contém informações relacionadas às classes. Os objetos de classe são usados para criar todos os objetos "regulares". O Java usa objetos de classe para executar o RTTI, mesmo se você estiver realizando operações como a conversão de tipo.
Cada classe gerará um objeto de classe correspondente, que é salvo em um arquivo .class. Todas as classes são carregadas dinamicamente na JVM quando são usadas pela primeira vez. Esta classe será carregada quando o programa criar uma referência a um membro estático da classe. Os objetos da classe são carregados apenas quando necessário e a inicialização estática é realizada quando a classe é carregada.
classe pública testMain {public static void main (string [] args) {System.out.println (xyz.name);}} classe xyz {public static string name = "luoxn28"; static {System.out.println ("xyz static block");}}}} construído ");}}O resultado da saída é:
O carregador de classe verifica primeiro se o objeto de classe desta classe foi carregado. Se não tiver sido carregado, o carregador de classe padrão procurará o arquivo .class correspondente com base no nome da classe.
Para usar as informações do tipo em tempo de execução, você deve obter uma referência ao objeto de classe do objeto (como um objeto base). Você pode usar a classe Class.ForName ("Base") para conseguir isso ou usar base.class. Observe que é interessante. Ao usar a função ".class" para criar uma referência a um objeto de classe, o objeto de classe não será inicializado automaticamente e o uso forname () inicializará automaticamente o objeto de classe. Os preparativos para o uso de classes geralmente têm as seguintes 3 etapas:
• Carregamento: concluído pelo carregador de classe, encontre o bytecode correspondente e crie um objeto de classe
• Link: verifique o bytecode na classe e aloce espaço para o domínio estático
• Inicialização: se a classe tiver uma superclasse, ela é inicializada e o inicializador estático e o bloco de inicialização estática serão executados.
classe pública base {static int num = 1; static {System.out.println ("base" + num);}} public class Main {public static void main (string [] args) {// blocos estáticos não serão inicializados classe clazz1 = base.class; system.out.println ("-----" "; Class.ForName ("ZZZ.Base");}} 2. Verifique antes da conversão do tipo
O compilador verificará se o tipo de transição para baixo é legal e, se não for legal, uma exceção será lançada. Antes de converter o tipo, você pode usar a instância para julgar.
classe base {} classe derivada estende a base {} public class Main {public static void main (string [] args) {base base = new Derived (); if (instância baseof derivada) {// aqui você pode down-convert system.out.println ("ok");} {System.out.println (não ok "); 3. Reflexão: Informações de tempo de execução
Se você não conhece o tipo exato de objeto, o RTTI pode lhe dizer, mas há um pré -requisito: esse tipo deve ser conhecido no tempo de compilação para que o RTTI possa ser usado para identificá -lo. A classe de classe suporta a reflexão juntamente com a biblioteca de classe Java.Lang.Reflect. Esta biblioteca de classes contém classes de campo, método e construtor. Os objetos dessas classes são criados pela JVM na startup para representar os membros correspondentes em classes desconhecidas. Dessa forma, você pode usar o Contratador para criar um novo objeto, usar os métodos get () e set () para obter e modificar os campos associados ao objeto de campo na classe e usar o método Invoke () para chamar o método associado ao objeto do método. Além disso, muitos métodos convenientes como getfields (), getMethods () e getConstructors () também podem ser chamados para retornar uma matriz representando campos, métodos e objetos construtores. Dessa forma, as informações do objeto podem ser completamente determinadas em tempo de execução sem saber nada sobre a aula no momento da compilação.
Não há nada mágico no mecanismo de reflexão. Ao lidar com um objeto do tipo desconhecido através da reflexão, a JVM simplesmente verifica o objeto para ver a qual classe específica ele pertence. Portanto, a classe dessa classe deve ser buscada para a JVM, na máquina local ou na rede. Portanto, a diferença real entre o RTTI e a reflexão é apenas:
• RTTI, o compilador abre e verifica os arquivos .Class no horário de compilação
• Reflita, abra e verifique os arquivos .Class em tempo de execução
public class Pessoa implementa serializável {nome da string privada; private int age; // get/set method} public static void main (string [] args) {pessoa pessoa = new pessoa ("luoxn28", 23); classe clazz = Pessoa.getclass (); campo [] campos = clazz.geldds (fieldfields = field (fieldclass; field.getName (); PropertyDescriptor descritor = new PropertyDescriptor (Key, Clazz); Método Método = Descriptor.getReadMethod (); Objeto Valor = Method.inVoke (Person); System.out.println (Key + ":" + Value);}}}}} O acima chama a função get da classe através do método getReadMethod (), e o método getWriteMethod () pode ser usado para chamar o método definido da classe. De um modo geral, não precisamos usar ferramentas de reflexão, mas elas são mais úteis na criação de código dinâmico. A reflexão é usada no Java para apoiar outros recursos, como serialização de objetos e javabeus.
4. Agente dinâmico
O modo proxy é fornecer operações adicionais ou diferentes, e os objetos inseridos são usados para substituir objetos "reais", que envolvem comunicação com objetos "reais", portanto o proxy geralmente atua como intermediário. O proxy dinâmico de Java está um passo à frente da idéia de proxy, que pode criar dinamicamente, criar, proxie e lidar com chamadas para os métodos proxy dinamicamente. Todas as chamadas feitas no proxy dinâmico são redirecionadas para um processador de chamada única, e seu trabalho é revelar o tipo de chamada e determinar a política correspondente. Aqui está um exemplo de um proxy dinâmico:
Classes de interface e implementação:
interface pública interface {void doSomething (); vazio algoLSE (string arg);} classe pública realObject implementa a interface {public void Dosomething () {System.out.println ("Dosomething");} public void algolse (string arg) {System.out.Println ") Processador de objeto de proxy dinâmico:
public class DynamicProxyHandler implementa InvocationHandler {Private Object Proxyed; public DynamicProxyHandler (Object Proxyed) {this.Proxyed = proxyed;}@SubstitionPublic Object INVOKE (Object Proxy, Método, Object [] args) lança ilegalActExExceptemExtEngTentEngTentEngMen, Método, Object [] args) lança ilegalAx. Proxy está funcionando. "); Método de retorno.invoke (proxyed, args);}} Classe de teste:
public class Main {public static void main (string [] args) {realObject real = new realObject (); interface proxy = (interface) proxy.newproxyInstance (interface.class.getclassloader (), new class [] {interface.class}, novo DynamicProxyHandler (real)); proxy.dosomething (); proxy.somethingelse ("luoxn28");}}O resultado da saída é o seguinte:
Você pode criar um proxy dinâmico chamando proxy estático de proxy proxy.newproxyInstance (). Este método requer um carregador de classe, uma lista de interfaces que você deseja que o proxy implemente (não uma classe ou classe abstrata) e uma classe de implementação do InvocationHandler. O proxy dinâmico pode redirecionar todas as chamadas para o processador de chamada; portanto, o construtor do processador de chamadas geralmente passa uma referência ao objeto "real", que encaminhará a solicitação quando o processador de chamada estiver executando a tarefa de mediação.
O exposto acima é o entendimento profundo da reflexão Java introduzida pelo editor a você. Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!