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

Tutorial di base Java

Java Controllo di flusso

Java Array

Java Orientato agli oggetti (I)

Java Orientato agli oggetti (II)

Java Orientato agli oggetti (III)

Gestione eccezioni Java

Java List

Java Queue (coda)

Java Map collection

Java Set collection

Java Input/Output (I/O)

Java Reader/Writer

Altri argomenti Java

Riflessione (Reflection) Java

In questo tutorial, impareremo la reflection, che è una caratteristica del programming Java che ci permette di verificare e modificare classi, metodi e altro.

In Java, la reflection ci permette di verificare e manipolare classi, interfacce, costruttori, metodi e campi in tempo di esecuzione.

Il nome della classe Java è Class

Prima di studiare la reflection in Java, dobbiamo conoscere una classe Java chiamata Class.

In Java esiste una classe chiamata Class, che nel momento dell'esecuzione conserva tutte le informazioni sugli oggetti e le classi.

L'oggetto Class descrive le proprietà di una classe specifica. L'oggetto viene utilizzato per eseguire la reflection.

Creare un oggetto di classe chiamato Class

Possiamo creare oggetti di Class, tramite:

  • Utilizzando il metodo forName()

forName() accetta un parametro di stringa (il nome della classe) e restituisce un oggetto Class. L'oggetto restituito fa riferimento alla classe specificata dalla stringa. Ad esempio,

Class Dog { }
Class c1 = Class.forName("Dog");
  • Utilizzando il metodo getClass()

 Il metodo getClass() utilizza un oggetto specifico della classe per creare un nuovo oggetto Class. Ad esempio,

Dog d1 = new Dog()
Class c1 = d1.getClass();
  • Utilizzando .class

Possiamo anche utilizzare.classCreazione di oggetti Class tramite estensione. Ad esempio,

Class c1 = Dog.class;

Dopo aver creato oggetti Class, possiamo utilizzarli per eseguire la reflection.

Ottieni interfaccia

Possiamo utilizzare il metodo getInterfaces() di Class per raccogliere informazioni sulle interfacce implementate dalla classe. Questo metodo restituisce un array di interfacce.

Esempio: ottieni interfaccia

import java.lang.Class;
import java.lang.reflect.*;
interface Animal {
   public void display();
}
interface Mammal {
   public void makeSound();
}
class Dog implements Animal, Mammal {
   public void display() {
      System.out.println("I am a dog.");
   }
   public void makeSound() {
      System.out.println("Bark bark");
   }
}
class ReflectionDemo {
  public static void main(String[] args) {
      try {
          //Crea un oggetto di classe Dog
          Dog d1 = new Dog();
          //Crea un oggetto Class utilizzando getClass()
          Class obj = d1.getClass();
        
          //Trova le interfacce implementate da Dog
          Class[] objInterface = obj.getInterfaces();
          for(Class c : objInterface) {
              //Stampa il nome dell'interfaccia
              System.out.println("Nome interfaccia: " + c.getName());
          }
      }
      catch(Exception e) {
          e.printStackTrace();
      }
   }
}

Risultato di output

Nome interfaccia: Animal
Nome interfaccia: Mammal

Ottieni superclasse e modificatore di accesso

Il metodo getSuperclass() della classe Class può essere utilizzato per ottenere informazioni sulla superclasse di una classe specifica.

Inoltre, Class fornisce un metodo getModifier() che restituisce i modificatori della classe in forma intera.

Esempio: ottieni superclasse e modificatore di accesso

import java.lang.Class;
import java.lang.reflect.*;
interface Animal {
   public void display();
}
public class Dog implements Animal {
   public void display() {
       System.out.println("I am a dog.");
   }
}
class ReflectionDemo {
   public static void main(String[] args) {
       try {
           //Crea un oggetto di classe Dog
           Dog d1 = new Dog();
           //Crea un oggetto Class utilizzando getClass()
           Class obj = d1.getClass();
           //Ottieni il modificatore di accesso di Dog in forma intera
           int modifier = obj.getModifiers();
           System.out.println("Modificatore: " + Modifier.toString(modifier));
           //找到Dog的超类
           Class superClass = obj.getSuperclass();
           System.out.println("Superclass: " + superClass.getName());
       }
       catch(Exception e) {
           e.printStackTrace();
       }
   }
}

Risultato di output

Modificatore: public
Superclass: Animal

反射字段,方法和构造函数

该软件包java.lang.reflect提供了可用于操作类成员的类。例如,

  • 方法类 - 提供有关类中方法的信息

  • 字段类 - 提供有关类中字段的信息

  • 构造函数类  - 提供有关类中构造函数的信息

Java 反射与字段

 我们可以使用Field类提供的各种方法检查和修改类的不同字段。

  • getFields() - 返回该类及其超类的所有公共字段

  • getDeclaredFields()  - 返回类的所有字段

  • getModifier() - 以整数形式返回字段的修饰符

  • set(classObject,value) - 使用指定的值设置字段的值

  • get(classObject) - 获取字段的值

  • setAccessible(boolean) - 使私有字段可访问

注意:如果我们知道字段名称,则可以使用

  • getField("fieldName") - 从类返回名称为fieldName的公共字段。

  • getDeclaredField("fieldName") - 从类返回名称为fieldName的字段。

示例:访问公共字段

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
  public String type;
}
class ReflectionDemo {
  public static void main(String[] args) {
     try{
         Dog d1 = new Dog();
          //创建Class对象
         Class obj = d1.getClass();
        //操纵Dog类的公共字段type
         Field field1 = obj.getField("type");
        //设置字段的值
         field1.set(d1, "labrador");
        //通过转换成字符串来获取字段的值
         String typeValue = (String)field1.get(d1);
         System.out.println("type: " + typeValue);
         //获取类型的访问修饰符
         int mod1 = field1.getModifiers();
         String modifier1 = Modifier.toString(mod1);
         System.out.println("修饰符: " + modifier1);
         System.out.println(" ");
     }
     catch(Exception e) {
         e.printStackTrace();
     }
  }
}

Risultato di output

type: labrador
Modificatore: public

示例:访问私有字段

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
 private String color;
}
class ReflectionDemo {
public static void main(String[] args) {
   try {
      Dog d1 = new Dog();
      //创建类Class对象
      Class obj = d1.getClass();
      //访问私有字段
      Field field2 = obj.getDeclaredField("color");
     
      //使私有字段可访问
      field2.setAccessible(true);
      //设置color值
      field2.set(d1, "brown");
      // get the value of type converting in String
      String colorValue = (String)field2.get(d1);
      System.out.println("color: " + colorValue);
      //获取color的访问修饰符
      int mod2 = field2.getModifiers();
      String modifier2 = Modifier.toString(mod2);
      System.out.println("modifier: " + modifier2);
   }
   catch(Exception e) {
      e.printStackTrace();
   }
 }
}

Risultato di output

color: brown
modifier: private

Java 反射与方法

像字段一样,我们可以使用Method类提供的各种方法来检查类的不同方法。

  • getMethods() - 返回该类及其超类的所有公共方法

  • getDeclaredMethod() - 返回该类的所有方法

  • getName() - 返回方法的名称

  • getModifiers() - 以整数形式返回方法的访问修饰符

  • getReturnType() - 返回方法的返回类型

示例:方法反射

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
   public void display() {
      System.out.println("I am a dog.");
   }
   protected void eat() {
      System.out.println("I eat dog food.");
   }
   private void makeSound() {
      System.out.println("Bark Bark");
   }
}
class ReflectionDemo {
   public static void main(String[] args) {
      try {
          Dog d1 = new Dog();
          //创建一个Class对象
          Class obj = d1.getClass();
          
          //使用getDeclaredMethod()获取所有方法
          Method[] methods = obj.getDeclaredMethods();
          //获取方法的名称
          for(Method m : methods) {
               
             System.out.println("方法名称: " + m.getName());
              
             //获取方法的访问修饰符
             int modifier = m.getModifiers();
             System.out.println("Modificatore: " + Modifier.toString(modifier));
              
             //获取方法的返回类型
             System.out.println("Return Types: " + m.getReturnType());
             System.out.println(" ");
          }
       }
       catch(Exception e) {
           e.printStackTrace();
       }
   }
}

Risultato di output

方法名称: display
Modificatore: public
Return type: void
方法名称: eat
修饰符: protected
返回类型: void
方法名称: makeSound
Modificatore: private
返回类型: void

Java 反射与构造函数

我们还可以使用Constructor类提供的各种方法检查类的不同构造函数。

  • getConstructors() - 返回该类的所有公共构造函数以及该类的超类

  • getDeclaredConstructor() -返回所有构造函数

  • getName() - 返回构造函数的名称

  • getModifiers() - 以整数形式返回构造函数的访问修饰符

  • getParameterCount() - 返回构造函数的参数数量

示例:构造函数反射

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
   public Dog() {
      
   }
   public Dog(int age) {
      
   }
   private Dog(String sound, String type) {
      
   }
}
class ReflectionDemo {
   public static void main(String[] args) {
      try {
           Dog d1 = new Dog();
           Class obj = d1.getClass();
           //使用getDeclaredConstructor()获取一个类中的所有构造函数
           Constructor[] constructors = obj.getDeclaredConstructors();
           for(Constructor c : constructors) {
               //Ottieni il nome del costruttore
               System.out.println("Nome del costruttore: " + c.getName());
               //Ottieni il modificatore di accesso del costruttore
               int modifier = c.getModifiers();
               System.out.println("Modificatore: " + Modifier.toString(modifier));
               //Ottieni il numero di parametri del costruttore
               System.out.println("Numero di parametri: " + c.getParameterCount());
          }
       }
       catch(Exception e) {
           e.printStackTrace();
       }
    }
}

Risultato di output

Nome del costruttore: Dog
Modificatore: public
Numero di parametri: 0
Nome del costruttore: Dog
Modificatore: public
Numero di parametri: 1
Nome del costruttore: Dog
Modificatore: private
Numero di parametri: 2