Neste tutorial, aprenderemos reflexão, um recurso da programação Java que nos permite inspecionar e modificar classes, métodos, etc.
Em Java, a reflexão nos permite inspecionar e manipular classes, interfaces, construtores, métodos e campos em tempo de execução.
Existe uma classe em Java chamada Class
que mantém todas as informações sobre objetos e classes em tempo de execução. O objeto de classe pode ser usado para realizar reflexão.
Reflexão das classes Java
Para refletir uma classe Java, primeiro precisamos criar um objeto de classe.
E, usando o objeto, podemos chamar vários métodos para obter informações sobre métodos, campos e construtores presentes em uma classe.
Existem três maneiras de criar objetos de Classe:
1. Usando o método forName ()
class Dog (… ) // create object of Class // to reflect the Dog class Class a = Class.forName("Dog");
Aqui, o forName()
método leva o nome da classe a ser refletida como seu argumento.
2. Usando o método getClass ()
// create an object of Dog class Dog d1 = new Dog(); // create an object of Class // to reflect Dog Class b = d1.getClass();
Aqui, estamos usando o objeto da classe Dog para criar um objeto da classe.
3. Usando a extensão .class
// create an object of Class // to reflect the Dog class Class c = Dog.class;
Agora que sabemos como podemos criar objetos do Class
. Podemos usar este objeto para obter informações sobre a classe correspondente em tempo de execução.
Exemplo: reflexão de classe Java
import java.lang.Class; import java.lang.reflect.*; class Animal ( ) // put this class in different Dog.java file public class Dog extends Animal ( public void display() ( System.out.println("I am a dog."); ) ) // put this in Main.java file class Main ( public static void main(String() args) ( try ( // create an object of Dog Dog d1 = new Dog(); // create an object of Class // using getClass() Class obj = d1.getClass(); // get name of the class String name = obj.getName(); System.out.println("Name: " + name); // get the access modifier of the class int modifier = obj.getModifiers(); // convert the access modifier to string String mod = Modifier.toString(modifier); System.out.println("Modifier: " + mod); // get the superclass of Dog Class superClass = obj.getSuperclass(); System.out.println("Superclass: " + superClass.getName()); ) catch (Exception e) ( e.printStackTrace(); ) ) )
Resultado
Nome: Cachorro Modificador: público Superclasse: Animal
No exemplo acima, criamos uma superclasse: Animal e uma subclasse: Dog. Aqui, estamos tentando inspecionar a classe Dog.
Observe a declaração,
Class obj = d1.getClass();
Aqui, estamos criando um objeto obj de Class usando o getClass()
método. Usando o objeto, estamos chamando diferentes métodos de Class.
- obj.getName () - retorna o nome da classe
- obj.getModifiers () - retorna o modificador de acesso da classe
- obj.getSuperclass () - retorna a superclasse da classe
Para saber mais sobre Class
, visite Java Class (documentação oficial do Java).
Observação : estamos usando a Modifier
classe para converter o modificador de acesso inteiro em uma string.
Campos reflexivos, métodos e construtores
O pacote java.lang.reflect
fornece classes que podem ser usadas para manipular membros da classe. Por exemplo,
- Classe de método - fornece informações sobre métodos em uma classe
- Classe de campo - fornece informações sobre os campos em uma classe
- Classe do construtor - fornece informações sobre os construtores em uma classe
1. Reflexão dos métodos Java
A Method
classe fornece vários métodos que podem ser usados para obter informações sobre os métodos presentes em uma classe. Por exemplo,
import java.lang.Class; import java.lang.reflect.*; class Dog ( // methods of the class public void display() ( System.out.println("I am a dog."); ) private void makeSound() ( System.out.println("Bark Bark"); ) ) class Main ( public static void main(String() args) ( try ( // create an object of Dog Dog d1 = new Dog(); // create an object of Class // using getClass() Class obj = d1.getClass(); // using object of Class to // get all the declared methods of Dog Method() methods = obj.getDeclaredMethods(); // create an object of the Method class for (Method m : methods) ( // get names of methods System.out.println("Method Name: " + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.println("Modifier: " + Modifier.toString(modifier)); // get the return types of method System.out.println("Return Types: " + m.getReturnType()); System.out.println(" "); ) ) catch (Exception e) ( e.printStackTrace(); ) ) )
Resultado
Nome do método: display Modificador: public Tipos de retorno: void Nome do método: makeSound Modificador: private Tipos de retorno: void
No exemplo acima, estamos tentando obter informações sobre os métodos presentes na classe Dog. Conforme mencionado anteriormente, primeiro criamos um objeto obj de Class
usar o getClass()
método.
Observe a expressão,
Method() methods = obj.getDeclaredMethod();
Aqui, o getDeclaredMethod()
retorna todos os métodos presentes dentro da classe.
Além disso, criamos um objeto m da Method
classe. Aqui,
- m.getName () - retorna o nome de um método
- m.getModifiers () - retorna o modificador de acesso de métodos em formato inteiro
- m.getReturnType () - retorna o tipo de retorno dos métodos
A Method
classe também fornece vários outros métodos que podem ser usados para inspecionar métodos em tempo de execução. Para saber mais, visite a classe Java Method (documentação oficial do Java).
2. Reflexão dos campos Java
Como os métodos, também podemos inspecionar e modificar diferentes campos de uma classe usando os métodos da Field
classe. Por exemplo,
import java.lang.Class; import java.lang.reflect.*; class Dog ( public String type; ) class Main ( public static void main(String() args) ( try ( // create an object of Dog Dog d1 = new Dog(); // create an object of Class // using getClass() Class obj = d1.getClass(); // access and set the type field Field field1 = obj.getField("type"); field1.set(d1, "labrador"); // get the value of the field type String typeValue = (String) field1.get(d1); System.out.println("Value: " + typeValue); // get the access modifier of the field type int mod = field1.getModifiers(); // convert the modifier to String form String modifier1 = Modifier.toString(mod); System.out.println("Modifier: " + modifier1); System.out.println(" "); ) catch (Exception e) ( e.printStackTrace(); ) ) )
Resultado
Valor: labrador Modificador: público
No exemplo acima, criamos uma classe chamada Dog. Inclui um campo público denominado type. Observe a declaração,
Field field1 = obj.getField("type");
Aqui, estamos acessando o campo público da classe Dog e atribuindo-o ao objeto field1 da classe Field.
Em seguida, usamos vários métodos da Field
classe:
- field1.set () - define o valor do campo
- field1.get () - retorna o valor do campo
- field1.getModifiers () - retorna o valor do campo em formato inteiro
Da mesma forma, também podemos acessar e modificar campos privados. No entanto, o reflexo do campo privado é um pouco diferente do campo público. Por exemplo,
import java.lang.Class; import java.lang.reflect.*; class Dog ( private String color; ) class Main ( public static void main(String() args) ( try ( // create an object of Dog Dog d1 = new Dog(); // create an object of Class // using getClass() Class obj = d1.getClass(); // access the private field color Field field1 = obj.getDeclaredField("color"); // allow modification of the private field field1.setAccessible(true); // set the value of color field1.set(d1, "brown"); // get the value of field color String colorValue = (String) field1.get(d1); System.out.println("Value: " + colorValue); // get the access modifier of color int mod2 = field1.getModifiers(); // convert the access modifier to string String modifier2 = Modifier.toString(mod2); System.out.println("Modifier: " + modifier2); ) catch (Exception e) ( e.printStackTrace(); ) ) )
Resultado
Valor: marrom Modificador: privado
No exemplo acima, criamos uma classe chamada Dog. A classe contém um campo privado denominado color. Observe a declaração.
Field field1 = obj.getDeclaredField("color"); field1.setAccessible(true);
Here, we are accessing color and assigning it to the object field1 of the Field
class. We then used field1 to modify the accessibility of color and allows us to make changes to it.
We then used field1 to perform various operations on the private field color.
To learn more about the different methods of Field, visit Java Field Class (official Java documentation).
3. Reflection of Java Constructor
We can also inspect different constructors of a class using various methods provided by the Constructor
class. For example,
import java.lang.Class; import java.lang.reflect.*; class Dog ( // public constructor without parameter public Dog() ( ) // private constructor with a single parameter private Dog(int age) ( ) ) class Main ( public static void main(String() args) ( try ( // create an object of Dog Dog d1 = new Dog(); // create an object of Class // using getClass() Class obj = d1.getClass(); // get all constructors of Dog Constructor() constructors = obj.getDeclaredConstructors(); for (Constructor c : constructors) ( // get the name of constructors System.out.println("Constructor Name: " + c.getName()); // get the access modifier of constructors // convert it into string form int modifier = c.getModifiers(); String mod = Modifier.toString(modifier); System.out.println("Modifier: " + mod); // get the number of parameters in constructors System.out.println("Parameters: " + c.getParameterCount()); System.out.println(""); ) ) catch (Exception e) ( e.printStackTrace(); ) ) )
Output
Constructor Name: Dog Modifier: public Parameters: 0 Constructor Name: Dog Modifier: private Parameters: 1
In the above example, we have created a class named Dog. The class includes two constructors.
We are using reflection to find the information about the constructors of the class. Notice the statement,
Constructor() constructors = obj.getDeclaredConstructor();
Aqui, estamos acessando todos os construtores presentes em Dog e atribuindo-os a um construtor de array do Constructor
tipo.
Em seguida, usamos o objeto c para obter diferentes informações sobre o construtor.
- c.getName () - retorna o nome do construtor
- c.getModifiers () - retorna os modificadores de acesso do construtor na forma inteira
- c.getParameterCount () - retorna o número de parâmetros presentes em cada construtor
Para saber mais sobre os métodos da Constructor
classe, visite a classe Constructor