Além de nos fornecer várias informações sobre como obter aulas durante o período de compilação, o Java também nos permite obter várias informações sobre as aulas durante o período de execução por meio da reflexão. Recuperar as informações da classe através da reflexão e, após a obtenção de informações da classe, você pode obter o seguinte conteúdo relacionado:
Este artigo também introduzirá a reflexão Java dos aspectos acima. Todos os códigos envolvidos neste artigo são refletidos
Primeiro, uma classe Java é lançada como objeto de pesquisa para reflexão. O conteúdo da classe é o seguinte:
Classe abstrata public paterbject implementa Runnable {public void Dosomething () {System.out.println ("Faça as coisas ..."); }} classe pública ExementObject estende o fébject {public int Age = 30; public string name = "byhieg"; Pontuação inteira privada = 60; public void printName () {System.out.println (nome); } public int getage () {Age de retorno; } public void setage (int Age) {this.age = Age; } public string getName () {return name; } public void setName (nome da string) {this.name = name; } public integer getScore () {Return Score; } public void SetScore (pontuação inteira) {this.score = score; } public ExemploObject () {} public ExemploObject (Nome da String) {} public ExemploObject (Int Age, Integer Score) {} @Override public void Dosomething () {super.Dosomething (); } @Override public void run () {System.out.println ("Run ..."); }}Objeto de classe
Nosso aplicativo usará o ponto de reflexão do conhecimento. Devemos querer obter as informações da classe em tempo de execução e fazer algumas operações específicas com base nas informações da classe. Então, a primeira coisa é obter as informações da classe e um objeto de classe é fornecido no JDK para salvar as informações da classe. Portanto, o primeiro passo na reflexão é obter o objeto de classe. Existem duas maneiras de obter objetos de classe no JDK.
O primeiro é que, se você souber o nome da classe ao escrever código, poderá obter diretamente o objeto de classe da seguinte maneira:
Class exampleObjectClass = ExampleObject.class;
O segundo tipo é que, se você não souber o nome da classe ao escrever o código, mas em tempo de execução, poderá obter uma sequência do nome da classe e obter o objeto de classe da seguinte maneira:
Class exampleObjectClass = Class.forName("cn.byhieg.reflectiontutorial.ExampleObject");
Observe que esse método precisa ter 2 condições. Primeiro, a string no forname deve ser o nome totalmente qualificado e, segundo, a classe de classe deve estar abaixo do caminho do caminho de classe, porque o método lançará uma exceção do ClassNotFoundException.
Depois de obter esse objeto de classe, você pode obter várias informações sobre a classe. Algumas informações foram mencionadas no início. Abaixo, vamos falar sobre as informações sobre a classe que não foram mencionadas.
Obtenha o nome da classe
Existem duas maneiras de obter o nome da classe, uma é GetName () e a outra é getSImpleName (). O primeiro recebe um nome totalmente qualificado e o segundo recebe o nome dessa classe sem um nome de pacote. Veja o seguinte exemplo: objeto de classe, que foi obtido através do código acima.
String fullClassName = ExpleObjectClass.getName (); String simpleclassName = ExpleObjectClass.getSimpleName (); System.out.println (fullclassName); System.out.println (simpleclassName); System.out.println (simpleclassName);
Os resultados são os seguintes:
cn.byhieg.reflectionTutorial.exampleObjectExampleObject
Obtenha o nome do pacote da classe, a classe pai e a interface de implementação
O nome do pacote e a classe pai da classe podem ser obtidos através do código a seguir.
// Obtenha o pacote de informações do pacote apackage = exemplobjectclass.getpackage (); System.out.println (Apackage); // obtenha classe de pai Superclass = ExemploObjectClass.getSuperclass (); System.out.println (superclass.getSimplename ());
Os resultados são os seguintes:
pacote cn.byhieg.reflectionTutorialfatherObject
Obviamente, obter o valor de retorno da classe pai também é um objeto de classe. Em seguida, você pode usar esse objeto para obter algumas informações sobre a classe pai, como julgar se a classe pai é uma classe abstrata.
System.out.println("父类是不是抽象类" + Modifier.isAbstract(superClass.getModifiers()));
O GetModifiers pode obter modificadores de classe, obtendo modificadores de classe. Obviamente, esses getModifiers podem não apenas ser chamados de objetos de classe, mas também os objetos do método podem ser chamados.
Você pode usar o método na classe java.lang.reflect.modifier para verificar o tipo do modificador:
Modifier.isabstract (int modificadores); modifier.isfinal (int modificadores); modifier.isinterface (int modificadores); modifier.isnative (int modificadores); modificadores.isprivate (Intodifiers); modificador.isprotect (intodificadores); modifier.ispublic (INTO Modificador); modificadores); modifier.ISSTRITT (INT modificadores); modifier.issynchronized (int modificadores); modifier.istransient (int modificadores); modificador.isVolatile (INT modificadores);
Além disso, também podemos implementar a interface pela classe pai
// obtenha a classe de interface [] classes = superclass.getInterfaces (); System.out.println ("Interfaces da classe pai" + classes [0]);Como as classes Java podem implementar muitas interfaces, elas usam matrizes, mas ao realmente usá -las, você precisa primeiro determinar o comprimento da matriz.
Abaixo, vamos nos concentrar em explicar o conteúdo listado acima.
Construtor
Usando a reflexão Java, você pode obter um construtor de classe e criar dinamicamente um objeto em tempo de execução com base no construtor. Primeiro, Java obtém uma instância do construtor por:
// construtorConstructor [] constructors = exemplobjectClass.getConstructors (); para (construtor construtor: construtores) {System.out.println (construtor.toString ()); }Os resultados são os seguintes:
public cn.byhieg.reflectionTutorial.exampleObject (int, java.lang.integer) public cn.byhieg.reflectionTutorial.exampleObject (java.lang.string) public cn.byhieg.reflectionTuTororial.exampleObject ()
Se você conhece o tipo de parâmetro do construtor para acessar com antecedência, poderá usar o seguinte método para obter o construtor especificado, como segue:
Construtor construtor = exemplobjectclass.getConstructor (string.class); System.out.println (construtor.toString ());
O resultado é obviamente:
public cn.byhieg.reflectiontutorial.ExampleObject(java.lang.String)
Outro construtor também pode ser obtido da seguinte maneira
Construtor construtor = exemplobjectclass.getConstructor (int.class, inteiro.class); System.out.println (construtor.toString ());
Além disso, se não conhecemos os parâmetros do construtor e só podemos obter todos os objetos do construtor, podemos obter os parâmetros que cada construtor usa da seguinte maneira:
Construtor [] constructors = ExpleObjectClass.getConstructors (); para (construtor construtor: construtores) {class [] parameterTypes = construtor.getParameterTypes (); System.out.println ("Os parâmetros do construtor são como segue =============================================================== ========================================================================= para (classe clz: parameterTypes) {System.out.println ("ParameterType" + clz.toString ());Os resultados são os seguintes:
Os parâmetros do construtor são os seguintes ================================== Tipo de parâmetro Classe Java.lang.String Parâmetros do construtor são os seguintes = parâmetros ===========GUMATR.
Aqui, pode -se observar que o método de construção sem parâmetros não imprime o resultado. O objeto de classe do tipo básico e o objeto de classe do tipo de referência são diferentes.
Agora, um objeto pode ser criado dinamicamente com base em várias informações do construtor.
Objeto objeto = construtor.NewInstance (1.100); System.out.println (object.toString ());
Existem duas condições para criar um objeto. O primeiro é criado através de um construtor de parâmetros. A segunda é que o objeto construtor deve ser obtido através do getConstructor que passa em informações de parâmetros.
A primeira condição é que, para objetos que podem ser criados sem métodos de construção de parâmetros, não há necessidade de obter o objeto construtor. O objeto de classe chama o método newInstance () e cria o objeto diretamente.
A segunda condição é que o objeto construtor deve ser obtido através do formulário ExemploObjectClass.getConstructor (String.class); Seria errado obter a matriz do construtor através do GetConstructors e, em seguida, chamar o objeto construtor especificado para criar o objeto no JDK1.8. Mas JDK1.6 é normal.
variável
Usando a reflexão Java, você pode obter informações variáveis de uma classe em tempo de execução e pode criar um objeto e definir seu valor variável de acordo com o método acima. Primeiro, todas as variáveis públicas são obtidas seguindo o seguinte método:
Campo [] campos = exemplobjectClass.getfields (); for (campo de campo: campos) {System.out.println ("variável é:" + field.toString ()); }Os resultados são os seguintes:
A variável é: public int cn.byhieg.reflectionTutorial.exampleObject.age A variável é: public java.lang.string cn.byhieg.reflectionTutorial.exampleObject.Name
Obviamente, todas as variáveis públicas obtidas são públicas e a pontuação variável privada acima não é obtida.
Da mesma maneira que o construtor é obtido, podemos especificar um nome de parâmetro e, em seguida, obter a variável especificada:
Campo de campo = exemplobjectclass.getfield ("idade"); System.out.println ("variável é:" + field.toString ());O nome obtido pelo método de tostragem da variável acima é muito longo. O Java fornece o método GetName para a classe de campo, que retorna o nome da variável escrita na classe. O código acima pode ser alterado para field.getName ().
A reflexão não apenas fornece uma maneira de obter variáveis, mas também fornece uma maneira de definir valores variáveis. Seguindo o método a seguir, você pode alterar o valor variável de uma classe gerada dinamicamente:
ExemploObject Object = ((ExemploObject) construtor1.newinstance ("byhieg")); System.out.println ("A idade original é" + object.age); field.set (objeto, 10); System.out.println ("A idade após a alteração é" + object.age);Os resultados são os seguintes:
A idade original é de 30 e a idade após a mudança é 10
De acordo com o código acima, você pode obter um objeto de campo chamado AGE, depois chamar o método definido do objeto, passar um objeto e o valor a ser alterado e, em seguida, pode alterar o valor do objeto. Observe que esse método não é apenas útil para variáveis de membros, mas também para variáveis estáticas. Obviamente, se for uma variável estática, não há problema em passar nulo sem passar pelo objeto.
método
Além de nos fornecer informações variáveis da classe, o Java Reflection também nos fornece informações de método. A reflexão nos permite obter o nome do método, os parâmetros do método, o tipo de retorno do método e os métodos de chamada.
Primeiro, obtenha o método através do seguinte código:
// O método público do método da classe de saída [] métodos = ExemploObjectClass.getMethods (); para (Método Método: Métodos) {System.out.println ("Method ="+ Method.getName ()); }Código que parece familiar como obter variáveis. O GetName é chamado diretamente aqui para escrever o nome do método na classe. Tendo escrito isso, você deve naturalmente pensar que o Java também fornece métodos específicos com base em parâmetros.
Método Método = ExemploObjectClass.getMethod ("Setage", int.class); System.out.println (métod.getName ());A diferença aqui é que o método getMethod também precisa passar nas informações do tipo de parâmetro, refletindo fornece um método para obter parâmetros do método e tipo de retorno. Exemplos de obtenção de parâmetros do método são os seguintes:
Método Método = ExemploObjectClass.getMethod ("Setage", int.class); System.out.println (métod.getName ()); para (classe clz: métod.getParameterTypes ()) {System.out.println ("Parâmetro do método" + clz.getName ()); }Os resultados são os seguintes:
O parâmetro int do método de definição
Um exemplo de obtenção do tipo de retorno do método é o seguinte:
System.out.println(method.getReturnType().getName());
Os resultados são os seguintes:
void
Além disso, a reflexão Java suporta métodos obtidos por meio de chamadas de invocar. Exemplos são os seguintes:
method.invoke(exampleObjectClass.newInstance(),1);
O primeiro parâmetro Invoke é esse objeto, e o segundo parâmetro é uma matriz de comprimento variável, e os parâmetros do método são passados. Assim como objetos de campo, para métodos estáticos, você pode passar nulo e chamar métodos estáticos.
Variáveis privadas e métodos privados
O método acima pode obter apenas métodos e variáveis públicas, mas não pode obter métodos e variáveis não públicos modificados. O Java fornece métodos adicionais para obter variáveis e métodos não públicos. Ou seja, variáveis e métodos privados são obtidos através dos métodos GetDecLaredFields e GetDecLaredMethods. Ele também suporta o uso do GetDecLaredField (nome da variável) e GetDecLaredMethod (nome do método) para obter o nome da variável especificada e o nome do método. No entanto, os objetos de campo e os objetos de método obtidos dessa maneira não podem ser usados diretamente. Esses objetos devem ser chamados de SetAccessible (true) para uso normal. O método a seguir pode ser o mesmo mencionado acima.
anotação
Primeiro, escreva uma classe contendo anotações:
@Myannotation (name = "byhieg", value = "hello world") public class AnoTationObject {@myannotation (name = "field", value = "variável") public string Field; @Myannotation (name = "método", value = "método") public void Dosomething () {System.out.println ("faça algo"); } public void Dootherthing (@myannotation (name = "param", value = "param") string param) {}}@retention (retentionPolicy.Runtime) public @Interface myannotation {public string name (); public string value ();}O Java nos fornece informações sobre a obtenção de anotações de classe no tempo de execução e podemos obter anotações de classe, anotações de método, anotações de parâmetros e anotações variáveis.
Como o método de aquisição acima, o Java fornece dois métodos de aquisição. Uma é obter todas as anotações e retornar uma matriz, e a segunda é especificar as anotações especificadas.
Vamos fazer uma anotação de aula como exemplo para explicar as duas maneiras a seguir.
Classe clz = anoTationObject.class; Anotação [] anotações = clz.getannotações (); Anotação anotação = clz.getAnnotation (anoTationObject.class);
Em seguida, o processamento subsequente pode ser realizado com base na anotação obtida. A seguir, é apresentado um exemplo de processamento:
para (anotação anotação: anotações) {if (instância de anotação de myannotation) {myannotation myannotation = (myannotation) anotação; System.out.println ("Nome:" + myannotation.name ()); System.out.println ("value:" + myannotation.value ()); }}As anotações de classe acima são obtidas chamando getannotações usando o objeto de classe. As anotações do método e as anotações variáveis são as mesmas. Eu chamo GetDecLaredAnnotações usando objetos de método e objetos de campo, respectivamente, para obter anotações. Não tenho muito a dizer. Veja o código de reflexão por exemplo
As anotações de parâmetros são um item relativamente problemático. O método de aquisição é comparado. A primeira etapa é obter o objeto do método primeiro e chamar GetParameterAnnotações. No entanto, esse valor de retorno é uma matriz bidimensional, porque o objeto de método possui muitos parâmetros e cada parâmetro pode ter muitas anotações. Exemplos são os seguintes:
Método Método1 = Clz.getMethod ("Dootherthing", String.class); Anotação [] [] anotaçãoInparam = Method1.getParameterAnnoTations (); Classe [] params = method1.getParameterTypes (); int i = 0; para (anotação [] anotações: anotaçãoInparam) {classe para = params [i ++]; para (anotação anotação: anotações) {if (instância de anotação de myannotation) {myannotation myannotation = (myannotation) anotação; System.out.println ("param:" + para.getName ()); System.out.println ("Nome:" + myannotation.name ()); System.out.println ("value:" + myannotation.value ()); }}}Genéricos
Como os genéricos do Java são implementados através da apagamento, é difícil obter informações diretamente sobre o tipo específico de genéricos parametrizados, mas podemos obter informações genéricas através de um formulário indireto usando reflexão. Por exemplo, a aula a seguir:
public class GenrouCObject {Lista public <String> Listas; list public <string> getLists () {listas de return; } public void setLists (list <String> listas) {this.lists = lists; }}Se um método retornar uma classe genérica, podemos chamar getGenericrendurnType através do objeto Método para GetGenericrendurnType para obter o que é o tipo de parametrização específico desta classe genérica. Veja o seguinte código:
Classe clz = genericobject.class; Método método = clz.getMethod ("getLists"); TIPO GERNICTYPE = METOD.GETGENERICRETRYTYPE (); if (instância do generictype de parametriedType) {parameterizedtype parameterizedtype = ((parameterizedtype) generictype); Type [] types = parametriedtype.getActualTyPearguments (); para (tipo de tipo: tipos) {classe realclz = ((classe) tipo); System.out.println ("Tipo de parametrização é:" + realclz); }}Os resultados são os seguintes:
参数化类型为: class java.lang.String
As etapas são um pouco pesadas, então a explicação a seguir é:
Recebi informações específicas sobre os genéricos observando os resultados.
Se nenhum método retornar um tipo genérico, também podemos obter o tipo parametrizado do tipo genérico pelo parâmetro do método como uma classe genérica, como o método setLists na classe acima. Exemplos são os seguintes:
Método setMethod = clz.getMethod ("setLists", list.class); Tipo [] genericParameterTypes = setMethod.getGenericParameterTypes (); para (tipo genéricoparameterType: genéricoparameterTypes) {System.out.println ("GenericParameterTypes é:" + genericParameterType.getTypeName ()); if (genicParameterType Instância de parameterizedType) {parameterizedTyPE ParametizedType = ((ParameterizedType) genéricoParameterType); System.out.println ("ParameterLeedType é:" + parametriedype.getTypeName ()); Tipos de tipo [] = parametriedtype.getActualTyPearguments (); para (tipo tipo: tipos) {System.out.println ("Tipo parametrizado é:" + ((classe) tipo) .getName ()); }}}Os resultados da execução são os seguintes:
GenericParameterTypes é: java.util.list <java.lang.string> parametriedtype é: java.util.list <java.lang.string> tipo parametrizado é: java.lang.string
Como os parâmetros do método podem ter mais de um tipo genérico, getGeNericParameterTypes para obter uma matriz e precisamos determinar se cada elemento tem um tipo parametrizado. As etapas subsequentes são semelhantes às acima, então não vou dizer muito.
Se mesmo os parâmetros do método não contêm classes genéricas, apenas o último caso é deixado, através do tipo de variável, ou seja, a classe de campo é usada. Exemplos são os seguintes:
Campo de campo = clz.getfield ("listas"); Tipo tipo = field.getGenerictype (); if (TIPE instância do parameterizedType) {ParametizedTyPE ParametizedType = (((ParameterLeedType) Tipo); Type [] types = parametriedtype.getActualTyPearguments (); para (tipo tipo 1: tipos) {System.out.println ("Tipo parametrizado:" + ((classe) tipo1) .getTypeName ()); }}O princípio é o mesmo que acima, exceto que o objeto de tipo é através do campo.getGenerictype (), então não vou dizer muito sobre as operações restantes.
Esta é a introdução à obtenção do tipo parametrizado de genéricos através da reflexão.
Variedade
A reflexão Java pode operar em uma matriz, incluindo a criação de uma matriz, o acesso a valores em uma matriz e obtendo um objeto de classe de uma matriz.
Vamos falar sobre isso simplesmente, criar uma matriz e acessar os valores na matriz: usar a classe de matriz em reflexão é a abaixo do pacote refletir.
// Crie uma matriz de tipo int com um comprimento de 3 int [] intray = (int []) Array.NewInstance (int.class, 3); // atribui um valor à matriz através da reflexão para (int i = 0; i <intray.length; i ++) {Array.set (Intarray, i, i+2); } // Matriz na forma de reflexão, obtenha o valor na matriz para (int i = 0; i <intray.length; i ++) {System.out.println (Array.get (INTARRAY, i)); }O exposto acima é criar uma matriz e acessar os valores na matriz usando reflexão.
Para objetos de classe que recebem uma matriz, você pode simplesmente usar int []. Classe ou usar classe.ForName, que é uma maneira estranha de escrever:
Classe clz = classe.ForName ("[i"); System.out.println (clz.getTypeName ());O resultado é:
int[]
A string nesse nome, [ representa uma matriz, eu represento um int, float é f , o dobro é D , etc. Se você deseja obter uma variedade de objetos comuns, use o seguinte formulário:
Class stringClz = Class.forName("[Ljava.lang.String;");
[ Digamos que seja uma matriz, o lado direito de L é o nome da classe, e o lado direito do tipo é A ; ;
Dessa forma, de obter o objeto de classe da matriz é muito pesado.
Depois de obter o objeto de classe da matriz, alguns de seus métodos exclusivos podem ser chamados, como chamar getComponentType para obter as informações de tipo dos membros da matriz. Por exemplo, uma matriz int é um tipo de membro, que é int.
System.out.println(clz.getComponentType().getTypeName());
O resultado é int
Resumir
Desta vez, as várias aplicações de reflexão terminam com isso, e pode haver explicações aprofundadas do conhecimento no futuro. Para um código específico, você pode olhar para o código de reflexão
No pacote SRC, existem várias classes e, na classe de teste, é o acesso a essas classes.
O exposto acima é todo o conteúdo deste artigo. Espero que o conteúdo deste artigo seja de ajuda para estudar ou trabalhar de todos. Eu também espero apoiar mais wulin.com!