In questo tutorial impareremo la riflessione, una funzionalità della programmazione Java che ci consente di ispezionare e modificare classi, metodi, ecc.
In Java, la reflection ci consente di ispezionare e manipolare classi, interfacce, costruttori, metodi e campi in fase di esecuzione.
Esiste una classe in Java denominata Class
che conserva tutte le informazioni su oggetti e classi in fase di esecuzione. L'oggetto di Class può essere utilizzato per eseguire la riflessione.
Riflessione sulle classi Java
Per riflettere una classe Java, dobbiamo prima creare un oggetto di Class.
Inoltre, utilizzando l'oggetto possiamo chiamare vari metodi per ottenere informazioni su metodi, campi e costruttori presenti in una classe.
Esistono tre modi per creare oggetti di Class:
1. Utilizzo del metodo forName ()
class Dog (… ) // create object of Class // to reflect the Dog class Class a = Class.forName("Dog");
Qui, il forName()
metodo prende il nome della classe da riflettere come argomento.
2. Utilizzo del metodo getClass ()
// create an object of Dog class Dog d1 = new Dog(); // create an object of Class // to reflect Dog Class b = d1.getClass();
Qui, stiamo usando l'oggetto della classe Dog per creare un oggetto di Class.
3. Utilizzo dell'estensione .class
// create an object of Class // to reflect the Dog class Class c = Dog.class;
Ora che sappiamo come creare oggetti di Class
. Possiamo usare questo oggetto per ottenere informazioni sulla classe corrispondente in fase di esecuzione.
Esempio: Java Class Reflection
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(); ) ) )
Produzione
Nome: Cane Modificatore: pubblico Superclasse: Animale
Nell'esempio sopra, abbiamo creato una superclasse: Animal e una sottoclasse: Dog. Qui, stiamo cercando di ispezionare la classe Dog.
Notare la dichiarazione,
Class obj = d1.getClass();
Qui, stiamo creando un oggetto obj di Class usando il getClass()
metodo. Usando l'oggetto, stiamo chiamando diversi metodi di Class.
- obj.getName () - restituisce il nome della classe
- obj.getModifiers () - restituisce il modificatore di accesso della classe
- obj.getSuperclass () - restituisce la super classe della classe
Per saperne di più Class
, visita Java Class (documentazione ufficiale Java).
Nota : stiamo usando la Modifier
classe per convertire il modificatore di accesso intero in una stringa.
Campi, metodi e costruttori riflettenti
Il pacchetto java.lang.reflect
fornisce classi che possono essere utilizzate per manipolare i membri della classe. Per esempio,
- Classe del metodo : fornisce informazioni sui metodi in una classe
- Classe di campo : fornisce informazioni sui campi in una classe
- Classe costruttore : fornisce informazioni sui costruttori in una classe
1. Riflessione sui metodi Java
La Method
classe fornisce vari metodi che possono essere utilizzati per ottenere informazioni sui metodi presenti in una classe. Per esempio,
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(); ) ) )
Produzione
Nome metodo: display Modificatore: public Tipi restituiti: void Nome metodo: makeSound Modificatore: private Tipi restituiti: void
Nell'esempio sopra, stiamo cercando di ottenere informazioni sui metodi presenti nella classe Dog. Come accennato in precedenza, abbiamo prima creato un oggetto per l' Class
utilizzo del getClass()
metodo.
Notare l'espressione,
Method() methods = obj.getDeclaredMethod();
Qui getDeclaredMethod()
restituisce tutti i metodi presenti all'interno della classe.
Inoltre, abbiamo creato un oggetto m della Method
classe. Qui,
- m.getName () - restituisce il nome di un metodo
- m.getModifiers () - restituisce il modificatore di accesso dei metodi in formato intero
- m.getReturnType () - restituisce il tipo restituito dei metodi
La Method
classe fornisce anche vari altri metodi che possono essere utilizzati per ispezionare i metodi in fase di esecuzione. Per saperne di più, visita la classe Metodo Java (documentazione Java ufficiale).
2. Riflessione sui campi Java
Come i metodi, possiamo anche ispezionare e modificare diversi campi di una classe utilizzando i metodi della Field
classe. Per esempio,
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(); ) ) )
Produzione
Valore: labrador Modificatore: pubblico
Nell'esempio precedente, abbiamo creato una classe denominata Dog. Include un campo pubblico denominato tipo. Notare la dichiarazione,
Field field1 = obj.getField("type");
Qui accediamo al campo pubblico della classe Dog e lo assegniamo all'oggetto field1 della classe Field.
Abbiamo quindi utilizzato vari metodi della Field
classe:
- field1.set () - imposta il valore del campo
- field1.get () - restituisce il valore di field
- field1.getModifiers () - restituisce il valore del campo in formato intero
Allo stesso modo, possiamo anche accedere e modificare i campi privati. Tuttavia, il riflesso del campo privato è leggermente diverso dal campo pubblico. Per esempio,
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(); ) ) )
Produzione
Valore: marrone Modificatore: privato
Nell'esempio precedente, abbiamo creato una classe denominata Dog. La classe contiene un campo privato denominato color. Nota la dichiarazione.
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();
Qui stiamo accedendo a tutti i costruttori presenti in Dog e assegnandoli a costruttori di array del Constructor
tipo.
Abbiamo quindi utilizzato l'oggetto c per ottenere diverse informazioni sul costruttore.
- c.getName () - restituisce il nome del costruttore
- c.getModifiers () - restituisce i modificatori di accesso del costruttore in forma intera
- c.getParameterCount () - restituisce il numero di parametri presenti in ogni costruttore
Per ulteriori informazioni su altri metodi della Constructor
classe, visita la classe Costruttore