java reflection tutorial with examples
Este tutorial em vídeo explica o que é o Reflection e como implementá-lo usando a API do Reflection:
Reflexão em Java é inspecionar e alterar o comportamento de um programa em tempo de execução.
Com a ajuda desta API de reflexão, você pode inspecionar classes, construtores, modificadores, campos, métodos e interfaces em tempo de execução. Por exemplo, você pode obter o nome da classe ou detalhes dos membros particulares da classe.
Leia todo o nosso Série de treinamento JAVA para obter mais informações sobre os conceitos Java.
Aqui está um tutorial em vídeo sobre o Java Reflection:
O que você aprenderá:
Reflexão em Java
Estamos cientes de que em uma determinada classe podemos modificar suas propriedades e métodos em tempo de compilação e é muito fácil fazer isso. Se as propriedades e métodos são anônimos ou têm nomes, eles podem ser alterados à nossa vontade durante o tempo de compilação.
Mas não podemos alterar essas classes, métodos ou campos em tempo de execução instantaneamente. Em outras palavras, é muito difícil alterar o comportamento de vários componentes de programação em tempo de execução, especialmente para objetos desconhecidos.
A linguagem de programação Java fornece um recurso chamado 'Reflexão' que nos permite modificar o comportamento de tempo de execução de uma classe ou campo ou método em tempo de execução.
Assim, um reflexo pode ser definido como um “Técnica de inspecionar e modificar o comportamento de tempo de execução de um objeto desconhecido em tempo de execução. Um objeto pode ser uma classe, um campo ou um método. ”
O Reflection é uma “Interface de Programação de Aplicativo” (API) fornecida por Java.
O processo de “Reflexão” é descrito abaixo.
Na representação acima, podemos ver que temos um objeto desconhecido. Em seguida, usamos a API Reflection neste objeto. Como resultado, podemos modificar o comportamento deste objeto em tempo de execução.
Assim, podemos usar a API Reflection em nossos programas com o propósito de modificar o comportamento do objeto. Os objetos podem ser qualquer coisa como métodos, interfaces, classes, etc. Nós inspecionamos esses objetos e então mudamos seu comportamento em tempo de execução usando a API de reflexão.
Em Java, o “java.lang” e “java.lang.reflect” são os dois pacotes que fornecem classes para reflexão. A classe especial “java.lang.Class” fornece os métodos e propriedades para extrair metadados usando os quais podemos inspecionar e modificar o comportamento da classe.
Usamos a API de reflexão fornecida pelos pacotes acima para modificar a classe e seus membros, incluindo campos, métodos, construtores, etc. em tempo de execução. Uma característica distintiva da Reflection API é que também podemos manipular os membros de dados privados ou métodos da classe.
A API de reflexão é usada principalmente em:
- O reflexo é usado principalmente em ferramentas de depuração, JUnit e estruturas para inspecionar e alterar o comportamento em tempo de execução.
- IDE (Ambiente de Desenvolvimento Integrado) Por exemplo. Eclipse IDE, NetBeans, etc.
- Ferramentas de teste etc.
- É utilizado quando seu aplicativo possui bibliotecas de terceiros e quando você deseja saber sobre as classes e métodos disponíveis.
API de reflexão em Java
Usando a API de reflexão, podemos implementar a reflexão nas seguintes entidades:
- Campo : A classe Field possui informações que usamos para declarar uma variável ou um campo como um tipo de dados (int, double, String, etc.), modificador de acesso (privado, público, protegido, etc.), nome (identificador) e valor.
- Método : A classe Method pode nos ajudar a extrair informações como modificador de acesso do método, tipo de retorno do método, nome do método, tipos de parâmetro do método e tipos de exceção levantados pelo método.
- Construtor : A classe do construtor fornece informações sobre o construtor da classe que inclui o modificador de acesso do construtor, o nome do construtor e os tipos de parâmetro.
- Editar : A classe do modificador nos fornece informações sobre um modificador de acesso específico.
Todas as classes acima fazem parte do pacote java.lang.reflect. A seguir, discutiremos cada uma dessas classes e usaremos exemplos de programação para demonstrar a reflexão sobre essas classes.
Vamos primeiro começar com a classe java.lang.Class.
java.lang.Class Class
A classe java.lang.The contém todas as informações e dados sobre classes e objetos em tempo de execução. Esta é a principal classe usada para reflexão.
A classe java.lang.Class fornece:
- Métodos para recuperar metadados de classe em tempo de execução.
- Métodos para inspecionar e modificar o comportamento de uma classe em tempo de execução.
Crie objetos java.lang.Class
Podemos criar objetos de java.lang.Class usando uma das seguintes opções.
como encontrar xpath em cromo para selênio
# 1) extensão .class
A primeira opção para criar um objeto de Classe é usando a extensão .class.
Por exemplo,se Test for uma classe, então podemos criar um objeto Class da seguinte maneira:
Class obj_test = Test.class;
Então, podemos usar o obj_test para realizar a reflexão, pois este objeto terá todas as informações sobre a classe Teste.
# 2) método forName ()
O método forName () recebe o nome da classe como um argumento e retorna o objeto Class.
Por exemplo,o objeto da classe Test pode ser criado da seguinte maneira:
class obj_test = Class.forName (“Test”);
# 3) método getClas ()
O método getClass () usa o objeto de uma classe para obter o objeto java.lang.Class.
Por exemplo,considere o seguinte trecho de código:
Test obj = new Test (); Class obj_test = obj.getClass ();
Na primeira linha, criamos um objeto da classe Test. Então, usando este objeto, chamamos o método “getClass ()” para obter um objeto obj_test de java.lang.Class.
Obter superclasse e modificadores de acesso
java.lang.class fornece um método “getSuperClass ()” que é usado para obter a superclasse de qualquer classe.
Da mesma forma, ele fornece um método getModifier () que retorna o modificador de acesso da classe.
O exemplo a seguir demonstra o método getSuperClass ().
import java.lang.Class; import java.lang.reflect.*; //define Person interface interface Person { public void display(); } //declare class Student that implements Person class Student implements Person { //define interface method display public void display() { System.out.println('I am a Student'); } } class Main { public static void main(String[] args) { try { // create an object of Student class Student s1 = new Student(); // get Class object using getClass() Class obj = s1.getClass(); // get the superclass of Student Class superClass = obj.getSuperclass(); System.out.println('Superclass of Student Class: ' + superClass.getName()); } catch(Exception e) { e.printStackTrace(); } } }
Resultado
No exemplo de programação acima, uma interface Person é definida com um método solitário ‘display ()’. Em seguida, definimos uma classe Student implementando a interface pessoal. No método principal, usamos o método getClass () para recuperar o objeto Class e, em seguida, acessamos o pai ou superclasse do objeto Student usando o método getSuperClass ().
Obtenha interfaces
Se a classe implementar algumas interfaces, podemos obter os nomes dessas interfaces usando o método getInterfaces () de java.lang.Class. Para isso, temos que realizar uma reflexão sobre a classe Java.
O exemplo de programação a seguir descreve o uso do método getInterfaces () no Java Reflection.
import java.lang.Class; import java.lang.reflect.*; //define Interface Animals and PetAnimals interface Animals { public void display(); } interface PetAnimals { public void makeSound(); } //define a class Dog that implements above interfaces class Dog implements Animals, PetAnimals { //define interface method display public void display() { System.out.println('This is a PetAnimal::Dog'); } //define interface method makeSound public void makeSound() { System.out.println('Dog makes sound::Bark bark'); } } class Main { public static void main(String[] args) { try { // create an object of Dog class Dog dog = new Dog(); // get class object Class obj = dog.getClass(); // get the interfaces implemented by Dog Class[] objInterface = obj.getInterfaces(); System.out.println('Class Dog implements following interfaces:'); //print all the interfaces implemented by class Dog for(Class citem : objInterface) { System.out.println('Interface Name: ' + citem.getName()); } } catch(Exception e) { e.printStackTrace(); } } }
Resultado
No programa acima, definimos duas interfaces, ou seja, Animais e Animais de Estimação. Em seguida, definimos uma classe Dog, que implementa ambas as interfaces.
No método principal, recuperamos o objeto da classe Dog em java.lang.Class para realizar a reflexão. Em seguida, usamos o método getInterfaces () para recuperar as interfaces que são implementadas pela classe Dog.
Reflexão: obter valor de campo
Conforme já mencionado, o pacote java.lang.reflect fornece a classe Field que nos ajuda a refletir o campo ou os membros de dados da classe.
Listados abaixo estão os métodos fornecidos pela classe Field para Reflexão de um campo.
Método | Descrição |
---|---|
getField ('fieldName') | Retorna o campo (público) com um nome de campo especificado. |
getFields () | Retorna todos os campos públicos (para classe e superclasse). |
getDeclaredFields () | Recupera todos os campos da classe. |
getModifier () | Retorna a representação inteira do modificador de acesso do campo. |
set (classObject, value) | Atribui o valor especificado ao campo. |
get (classObject) | Recupera o valor do campo. |
setAccessible (booleano) | Torne o campo privado acessível passando verdadeiro. |
getDeclaredField ('fieldName') | Retorna o campo com um nome especificado. |
A seguir, são apresentados dois exemplos de reflexão que demonstram a reflexão sobre o campo público e privado.
O programa Java abaixo demonstra a reflexão sobre um campo público.
import java.lang.Class; import java.lang.reflect.*; class Student { public String StudentName; } class Main { public static void main(String[] args) { try{ Student student = new Student(); // get an object of the class Class Class obj = student.getClass(); // provide field name and get the field info Field student_field = obj.getField('StudentName'); System.out.println('Details of StudentName class field:'); // set the value of field student_field.set(student, 'Lacey'); // get the access modifier of StudentName int mod1 = student_field.getModifiers(); String modifier1 = Modifier.toString(mod1); System.out.println('StudentName Modifier::' + modifier1); // get the value of field by converting in String String typeValue = (String)student_field.get(student); System.out.println('StudentName Value::' + typeValue); } catch(Exception e) { e.printStackTrace(); } } }
Resultado
Neste programa, declaramos uma classe “Student” com um campo público StudentName. Em seguida, usando a interface API da classe Field, realizamos uma reflexão sobre o campo StudentName e recuperamos seu modificador de acesso e valor.
O próximo programa realiza a reflexão sobre um campo privado da aula. As operações são semelhantes, exceto que há uma chamada de função extra feita para o campo privado. Temos que chamar setAccessible (true) para o campo privado. Em seguida, fazemos uma reflexão sobre esse campo de maneira semelhante à do campo público.
import java.lang.Class; import java.lang.reflect.*; class Student { private String rollNo; } class Main { public static void main(String[] args) { try { Student student = new Student(); // get the object for class Student in a Class. Class obj = student.getClass(); // access the private field Field field2 = obj.getDeclaredField('rollNo'); // make the private field accessible field2.setAccessible(true); // set the value of rollNo field2.set(student, '27'); System.out.println('Field Information of rollNo:'); // get the access modifier of rollNo int mod2 = field2.getModifiers(); String modifier2 = Modifier.toString(mod2); System.out.println('rollNo modifier::' + modifier2); // get the value of rollNo converting in String String rollNoValue = (String)field2.get(student); System.out.println('rollNo Value::' + rollNoValue); } catch(Exception e) { e.printStackTrace(); } } }
Resultado
Reflexão: Método
Semelhante aos campos da classe, também podemos realizar a reflexão sobre os métodos da classe e modificar seu comportamento em tempo de execução. Para isso, usamos a classe Method do pacote java.lang.reflect.
A seguir estão listadas as funções fornecidas pela classe Method para reflexão do método da classe.
Método | Descrição |
---|---|
getMethods () | Recupera todos os métodos públicos definidos na classe e sua superclasse. |
getDeclaredMethod () | Retorna métodos declarados na classe. |
getName () | Retorna os nomes dos métodos. |
getModifiers () | Retorna a representação inteira do modificador de acesso do método. |
getReturnType () | Retorna o tipo de retorno do método. |
O exemplo abaixo mostra o reflexo dos métodos de classe em Java usando as APIs acima.
import java.lang.Class; import java.lang.reflect.*; //declare a class Vehicle with four methods class Vehicle { public void display() { System.out.println('I am a Vehicle!!'); } protected void start() { System.out.println('Vehicle Started!!!'); } protected void stop() { System.out.println('Vehicle Stopped!!!'); } private void serviceVehicle() { System.out.println('Vehicle serviced!!'); } }class Main { public static void main(String[] args) { try { Vehicle car = new Vehicle(); // create an object of Class Class obj = car.getClass(); // get all the methods using the getDeclaredMethod() in an array Method[] methods = obj.getDeclaredMethods(); // for each method get method info for(Method m : methods) { System.out.println('Method Name: ' + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.print('Modifier: ' + Modifier.toString(modifier) + ' '); // get the return type of method System.out.print('Return Type: ' + m.getReturnType()); System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Resultado
No programa acima, vemos que o método getDeclaredMethods retorna a matriz de métodos declarada pela classe. Em seguida, iteramos por meio desse array e exibimos as informações de cada método.
Reflexão: Construtor
Podemos usar a classe “Construtor” do pacote java.lang.reflect para inspecionar e modificar os construtores de uma classe Java.
A classe construtora fornece os seguintes métodos para essa finalidade.
Método | Descrição |
---|---|
getConstructors () | Retorna todos os construtores declarados na classe e sua superclasse. |
getDeclaredConstructor () | Retorna todos os construtores declarados. |
getName () | Recupera o nome do construtor. |
getModifiers () | Retorna a representação inteira do modificador de acesso dos construtores. |
getParameterCount () | Retorna o número total de parâmetros para um construtor. |
O exemplo de reflexão abaixo demonstra o reflexo dos construtores de uma classe em Java. Como a reflexão do método, aqui também o método getDeclaredConstructors retorna uma matriz de construtores para uma classe. Em seguida, percorremos essa matriz de construtor para exibir informações sobre cada construtor.
import java.lang.Class; import java.lang.reflect.*; //declare a class Person with three constructors class Person { public Person() { } //constructor with no parameters public Person(String name) { } //constructor with 1 parameter private Person(String name, int age) {} //constructor with 2 parameters } class Main { public static void main(String[] args) { try { Person person = new Person(); Class obj = person.getClass(); // get array of constructors in a class using getDeclaredConstructor() Constructor[] constructors = obj.getDeclaredConstructors(); System.out.println('Constructors for Person Class:'); for(Constructor c : constructors) { // get names of constructors System.out.println('Constructor Name: ' + c.getName()); // get access modifier of constructors int modifier = c.getModifiers(); System.out.print ('Modifier: ' + Modifier.toString(modifier) + ' '); // get the number of parameters in constructors System.out.println('Parameters: ' + c.getParameterCount()); //if there are parameters, get parameter type of each parameter if(c.getParameterCount() > 0){ Class[] paramList=c.getParameterTypes(); System.out.print ('Constructor parameter types :'); for (Class class1 : paramList) { System.out.print(class1.getName() +' '); } } System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Resultado
Desvantagens da reflexão
A reflexão é poderosa, mas não deve ser usada indiscriminadamente. Se for possível operar sem usar reflexão, então é preferível evitar usá-la.
Listados abaixo estão algumas desvantagens do Reflection:
- Sobrecarga de desempenho: Embora a reflexão seja um recurso poderoso, as operações reflexivas ainda têm um desempenho mais lento do que as operações não reflexivas. Portanto, devemos evitar o uso de reflexos em aplicativos de desempenho crítico.
- Restrições de segurança: Como o reflexo é um recurso de tempo de execução, pode exigir permissões de tempo de execução. Portanto, para os aplicativos que exigem que o código seja executado em uma configuração de segurança restrita, a reflexão pode ser inútil.
- Exposição de internos: Usando reflexão, podemos acessar campos e métodos privados em uma classe. Assim, a reflexão quebra a abstração que pode tornar o código não portável e disfuncional.
perguntas frequentes
P # 1) Por que o Reflection é usado em Java?
Responda: Usando reflexão, podemos inspecionar classes, interfaces, construtores, campos e métodos em tempo de execução, mesmo que sejam anônimos em tempo de compilação. Essa inspeção nos permite modificar o comportamento dessas entidades em tempo de execução.
Q # 2) Onde o Reflection é usado?
Responda: A reflexão é usada para escrever estruturas que interoperam com classes definidas pelo usuário, em que o programador nem sabe quais serão as classes ou outras entidades.
Q # 3) O Java Reflection é lento?
Responda: Sim, é mais lento do que o código de não reflexão.
Q # 4) O Java Reflection é ruim?
Responda: De certa forma, sim. Em primeiro lugar, perdemos a segurança do tempo de compilação. Sem segurança de tempo de compilação, podemos obter erros de tempo de execução que podem afetar os usuários finais. Também será difícil depurar o erro.
Q # 5) Como você interrompe um Reflection em Java?
Responda: Simplesmente evitamos usar reflexão escrevendo operações de não reflexão. Ou talvez possamos usar alguns mecanismos genéricos, como uma validação personalizada com reflexão.
Mais sobre o Java Reflection
O pacote java.lang.reflect possui as classes e interfaces para fazer reflexão. E o java.lang.class pode ser usado como um ponto de entrada para a reflexão.
Como obter os objetos de classe:
1. Se você tiver instância de um objeto,
classe c = obj.getclass ();
2. Se você conhece o tipo da aula,
classe c = type.getClass ();
3. Se você souber o nome da turma,
Classe c = Class.forName (“com.demo.Mydemoclass”);
Como obter os membros da classe:
Os membros da classe são campos (variáveis de classe) e métodos.
- getFields () - Usado para obter todos os campos, exceto os campos privados.
- getDeclaredField () - Usado para obter os campos privados.
- getDeclaredFields () - Usado para obter os campos privado e público.
- getMethods () - Usado para obter todos os métodos, exceto os métodos privados.
- getDeclaredMethods () –Usado para obter os métodos públicos e privados.
Programas de demonstração:
ReflectionHelper.java:
Esta é a classe onde iremos inspecionar usando a API de reflexão.
como executar arquivos .jar windows 10
class ReflectionHelper { private int age; private String name; public String deptName; public int empID; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
ReflectionDemo.java
public class ReflectionDemo { public static void main(String[] args) throws NoSuchFieldException, SecurityException { //get the class Class ReflectionHelperclass=ReflectionHelper.class; //get the name of the class String className = ReflectionHelperclass.getName(); System.out.println('className=='+className); System.out.println('getModifiers'+ReflectionHelperclass.getModifier s()); System.out.println('getSuperclass'+ReflectionHelperclass.getSupercla ss()); System.out.println('getPackage'+ReflectionHelperclass.getPackage()); Field[] fields =ReflectionHelperclass.getFields(); //getting only the public fields for(Field oneField : fields) { Field field = ReflectionHelperclass.getField(oneField.getName()); String fieldname = field.getName(); System.out.println('only the public fieldnames:::::'+fieldname); } //getting all the fields of the class Field[] privatefields =ReflectionHelperclass.getDeclaredFields(); for(Field onefield : privatefields) { Field field = ReflectionHelperclass.getDeclaredField(onefield.getName()); String fieldname = field.getName(); System.out.println('all the fieldnames in the class:::'+fieldname); } Method[] methods =ReflectionHelperclass.getDeclaredMethods(); for(Method m: methods) { System.out.println('methods::::'+m.getName()); } }}
Conclusão
Este tutorial explicou a API do Reflection em Java em detalhes. Vimos como realizar a reflexão de classes, interfaces, campos, métodos e construtores, juntamente com algumas desvantagens da reflexão.
O reflexo é um recurso relativamente avançado em Java, mas deve ser usado por programadores que possuem um domínio da linguagem. Isso ocorre porque pode causar erros e resultados inesperados se não for usado com cuidado.
Embora a reflexão seja poderosa, ela deve ser usada com cuidado. No entanto, usando reflexão, podemos desenvolver aplicativos que desconhecem classes e outras entidades até o tempo de execução.
=> Dê uma olhada no guia para iniciantes em Java aqui.
Leitura recomendada
- Tutorial da classe Java Scanner com exemplos
- Java Integer e classe Java BigInteger com exemplos
- Tutorial JAVA para iniciantes: mais de 100 tutoriais práticos em vídeo Java
- Introdução à linguagem de programação Java - tutorial em vídeo
- O que é Java Vector | Tutorial da classe Java Vector com exemplos
- Interface Java e tutorial de classe abstrata com exemplos
- Método Java substring () - Tutorial com exemplos
- Tutorial do Java Collections Framework (JCF)