English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Explicação detalhada da reflexão no Java

Índice de leitura

  1. API de reflexão do Java
  2. Criar instância de objeto através de reflexão
  3. Chamada de método privado através da reflexão
  4. Sobre o ferramenta javap
  5. Referências

API de reflexão do Java

Reflexão do JavaRefere-se ao processo de obter atributos e métodos da classe ou modificar o comportamento da classe durante o estado de execução.

Classe java.lang.ClassFornece muitos métodos para obter metadados, verificar e alterar o comportamento da classe durante a execução.

A reflexão do Java envolve principalmente os pacotes java.lang e java.lang.reflect.

Exemplos de cenários de aplicação de reflexão

  1. IDE, como o Eclipse, MyEclipse, NetBeans e outros;
  2. Debuggers;
  3. Ferramentas de teste, etc;
  4. Vários frameworks, como spring, hibernate, etc;

Classe java.lang.Class

A classe java.lang.Class oferece as seguintes duas funções principais:

  1. Fornece métodos para acessar os metadados da classe durante a execução;
  2. Fornece métodos para verificar e modificar o comportamento da classe em tempo de execução;

Métodos comuns da classe java.lang.Class

Method Description
1) public String getName() Retorna o nome da classe
2) public static Class forName(String className)throws ClassNotFoundException Carrega a classe e retorna o objeto Class
3) public Object newInstance()throws InstantiationException,IllegalAccessException Cria um objeto de instância
4) public boolean isInterface() Julga se é uma interface
5) public boolean isArray() Julga se é um array
6) public boolean isPrimitive() Julga se é um tipo de dados original
7) public Class getSuperclass() Retorna a referência da classe pai Class
8) public Field[] getDeclaredFields()throws SecurityException Retorna o array de campos de propriedade membro da classe
9) public Method[] getDeclaredMethods()throws SecurityException Retorna o array de métodos da classe
10) public Constructor[] getDeclaredConstructors()throws SecurityException Retorna o array de métodos da classe
11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException Retorna o método especificado no tipo de parâmetro da classe

Como obter o objeto Class

Existem três maneiras, conforme a seguir:

  1. O método forName() da classe Class, carregamento dinâmico, início da execução, começa a carregar a classe e faz a inicialização estática da classe
  2. Método getClass() do objeto, carregamento estático (carregado no tempo de compilação)
  3. Sintaxe .class, carregamento estático (carregado no tempo de compilação)

Exemplo do método forName():

Pode ser usado para carregamento dinâmico, quando você saber o nome completo da classe, você pode usar este método. Atenção, os tipos de dados primitivos não se aplicam a este método;

package tmp;
class Simple
{
}
public class Test
{
 public static void main(String args[]) throws ClassNotFoundException
 {
 try63Class<&#
 System.out.println(c.getName());
 System.out.println(c.getSimpleName());
 }
}
tmp.Simple
Simple

Exemplo do método getClass():

Obter o objeto Class a partir do objeto de instância

package tmp;
class Simple
{
}
public class Test
{
 void printName(Object obj)
 {
 }
 public static void main(String args[])
 {
 Simple s = new Simple();
 try63; extends Object> c = s.getClass();
 System.out.println(c.getName());
 System.out.println(c.getSimpleName());
 }
}
tmp.Simple
Simple

Exemplo de sintaxe .class

Aplicável ao nome da classe, também pode ser aplicado aos tipos de dados primitivos, conforme exemplo a seguir:

package tmp;
public class Test
{
 public static void main(String args[])
 {
 Class<Boolean> c = boolean.class;
 System.out.println(c.getName());
 Class<Test> c2 = Test.class;
 System.out.println(c2.getName());
 }
}
boolean
tmp.Test

Determinar o tipo do objeto Class

Os seguintes métodos podem ser usados para determinar o tipo do objeto Class:

1) public boolean isInterface(): Se corresponde a uma interface
2) public boolean isArray(): Se corresponde a um array
3) public boolean isPrimitive(): Se corresponde ao tipo de dados original

Exemplo de código:

package tmp;
class Simple
{
}
interface My
{
}
public class Test
{
 public static void main(String args[])
 {
 this.msg = s;
 {
 try63Class<&#
 System.out.println(c.isInterface());
 try63;> c2 = Class.forName("tmp.My");
 System.out.println(c2.isInterface());
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}
false
true

Criar instância de objeto através de reflexão

Existem duas maneiras, conforme abaixo:

  1. Criado através do método newInstance() do objeto Class, este método só pode chamar o construtor sem parâmetros;
  2. Criado através do método newInstance() do objeto Constructor, este método é aplicável a métodos de construtor com parâmetros e também pode quebrar o padrão Singleton, chamando o construtor privado;

所以,通常来讲,第二种方式比第一种使用范围更广。

Portanto, geralmente falando, a segunda maneira é mais ampla em termos de uso do que a primeira.

package tmp;
class Simple
{
 private String msg;
 {
 Exemplo de chamada do método newInstance() do objeto Class
 }
}
public class Test
{
 public static void main(String args[])
 {
 this.msg = s;
 {
 try63Class<&#
 System.out.println("Hello Java");
 s.message();
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}

Simple s = (Simple) c.newInstance();

Hello Java

Exemplo de chamada do método newInstance() do objeto Constructor

package tmp;
Atenção, aqui pode-se obter o construtor específico de acordo com o tipo do parâmetro传入参数的类型来得到指定的构造方法,还可以改变构造方法的访问权限限制。
class Simple
{
 import java.lang.reflect.Constructor;
 private String msg;
 {
 void message() + System.out.println("Hello Java,"
 }
 msg);
 private Simple(String s){
 }
}
public class Test
{
 public static void main(String args[])
 {
 this.msg = s;
 {
 try63Class<&#
 ;> c = Class.forName("tmp.Simple");63;> con = c.getDeclaredConstructor(String.class);
 con.setAccessible(true);
 Simple s = (Simple) con.newInstance("...");
 s.message();
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}

Hello Java,...

Chamada de método privado através da reflexão

Através da reflexão, podemos chamar métodos privados de outras classes, principalmente envolvendo as classes java.lang.Class e java.lang.reflect.Method;

Aqui, principalmente são usados os métodos setAccessible e invoke da classe Method, o primeiro modifica as permissões de acesso, e o segundo chama o método.

Através da chamada de exemplo de método privado com parâmetros:

package tmp;
import java.lang.reflect.Method;
class A
{
 private void cube(int n)
 {
 System.out.println(n * n * n);
 }
}
class Test
{
 public static void main(String args[]) throws Exception
 {
 Class<A> c = A.class;
 Object obj = c.newInstance();
 Method m = c.getDeclaredMethod("cube", new Class[]{int.class});
 m.setAccessible(true);
 m.invoke(obj, 4);
 }
}

Sobre o ferramenta javap

O comando javap pode descompilar os arquivos bytecode do java, mostrando informações de campos, métodos de construção e métodos comuns no arquivo class;

Instrução de uso:

Exemplo javap java.lang.Object

javap -Exemplo de c Test:

Escreva uma classe Test simples, conforme abaixo:

package tmp;
class Simple
{
}
public class Test
{
 public static void main(String args[])
 {
 System.out.println("Hello");
 }
}

Digite javap -c Test:

Referências

Basicamente é uma tradução, com algumas pequenas modificações

http://www.javatpoint.com/java-reflexão

Isso é o conteúdo completo deste artigo, esperamos que o conteúdo deste artigo possa trazer um pouco de ajuda para o seu aprendizado ou trabalho, e também esperamos que você apoie mais o tutorial de clamor!

Declaração: O conteúdo deste artigo foi extraído da internet, pertence ao respectivo proprietário, o conteúdo foi contribuído e carregado voluntariamente pelos usuários da internet, este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidade por questões legais relacionadas. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie um e-mail para: notice#w3Declaração: O conteúdo deste artigo foi extraído da internet, pertence ao respectivo proprietário, o conteúdo foi contribuído e carregado voluntariamente pelos usuários da internet, este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidade por questões legais relacionadas. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie um e-mail para: notice#w

Você também pode gostar