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

Основной учебник Java

Java Управление потоком

Java Массив

Java Ориентированное на объекты (I)

Java Ориентированное на объекты (II)

Java Ориентированное на объекты (III)

Обработка исключений Java

Java Список (List)

Java Queue (очередь)

Java Map-сборники

Java Set-сборники

Java Ввод/вывод (I/O)

Java Reader/Writer

Другие темы Java

Reflection Java

В этом руководстве мы изучим отражение, это функция программирования Java, которая позволяет нам проверять и изменять классы, методы и т.д.

В Java反射 позволяет нам проверять и обрабатывать классы, интерфейсы, конструкторы, методы и поля во время выполнения.

Имя класса Java - Class

Прежде чем изучать отражение в Java, нам нужно узнать о классе Java под названием Class.

В Java существует класс под названием Class, который сохраняет все informacje о объектах и классах во время выполнения.

Объект класса Class описывает свойства определенного класса. Этот объект используется для выполнения отражения.

Создать объект класса с именем Class

Мы можем создать объект класса Class, используя:

  • 使用forName()方法

forName()接受字符串参数(类的名称)并返回Class对象。返回的对象引用字符串指定的类。例如,

Class Dog {  }
Class c1 = Class.forName("Dog");
  • 使用getClass()方法

 getClass()方法使用特定类的对象来创建新的对象Class。例如,

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

我们还可以使用.class扩展名创建Class对象。例如,

Class c1 = Dog.class;

创建Class对象后,我们可以使用这些对象执行反射。

获取接口

我们可以使用Class的getInterfaces()方法来收集类实现的接口的信息。此方法返回一个接口数组。

示例:获取接口

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 {
          //创建Dog类的对象
          Dog d1 = new Dog();
          //使用getClass()创建Class对象
          Class obj = d1.getClass();
        
          //查找Dog实现的接口
          Class[] objInterface = obj.getInterfaces();
          for(Class c : objInterface) {
              //打印接口名称
              System.out.println("Interface Name: " + c.getName());
          }
      }
      catch(Exception e) {
          e.printStackTrace();
      }
   }
}

Результат вывода

Interface Name: Animal
Interface Name: Mammal

获取超类和访问修饰符

类Class的方法getSuperclass()可用于获取有关特定类的超类的信息。

而且,Class提供了一种getModifier()方法,该方法以整数值返回类的修饰符。

示例:获取超类和访问修饰符

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 {
           //创建Dog类的对象
           Dog d1 = new Dog();
           //使用getClass()创建Class对象
           Class obj = d1.getClass();
           //获取Dog的访问修饰符的整数值
           int modifier = obj.getModifiers();
           System.out.println("Декоратор: " + Modifier.toString(modifier));
           // Найти суперкласс Dog
           Class superClass = obj.getSuperclass();
           System.out.println("Superclass: " + superClass.getName());
       }
       catch(Exception e) {
           e.printStackTrace();
       }
   }
}

Результат вывода

Декоратор: 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("тип: " + typeValue);
         // Получение доступа修饰符 типа
         int mod1 = field1.getModifiers();
         String modifier1 = Modifier.toString(mod1);
         System.out.println("Модификатор: " + modifier1);
         System.out.println(" ");
     }
     catch(Exception e) {
         e.printStackTrace();
     }
  }
}

Результат вывода

тип: labrador
Декоратор: 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");
      //Получение значения типа, преобразованного в строку
      String colorValue = (String)field2.get(d1);
      System.out.println("цвет: " + colorValue);
      //Получение модификатора доступа color
      int mod2 = field2.getModifiers();
      String modifier2 = Modifier.toString(mod2);
      System.out.println("модификатор: " + modifier2);
   }
   catch(Exception e) {
      e.printStackTrace();
   }
 }
}

Результат вывода

цвет: brown
модификатор: 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("Декоратор: " + Modifier.toString(modifier));
              
             //Получение типа возвращаемого значения метода
             System.out.println("Return Types: " + m.getReturnType());
             System.out.println(" ");
          }
       }
       catch(Exception e) {
           e.printStackTrace();
       }
   }
}

Результат вывода

Имя метода: display
Декоратор: public
Return type: void
Имя метода: eat
Модификатор: protected
Возврат типа: void
Имя метода: makeSound
Декоратор: 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) {
               //Получение имени конструктора
               System.out.println("Имя конструктора: " + c.getName());
               //Получение доступа修饰ителя конструктора
               int modifier = c.getModifiers();
               System.out.println("Декоратор: " + Modifier.toString(modifier));
               //Получение количества параметров конструктора
               System.out.println("Количество параметров: " + c.getParameterCount());
          }
       }
       catch(Exception e) {
           e.printStackTrace();
       }
    }
}

Результат вывода

Имя конструктора: Dog
Декоратор: public
Количество параметров: 0
Имя конструктора: Dog
Декоратор: public
Количество параметров: 1
Имя конструктора: Dog
Декоратор: private
Количество параметров: 2