Разговор об отражении в java

Java задняя часть
Разговор об отражении в java

Эта статья участвовала в "Проект «Звезда раскопок»», чтобы выиграть творческий подарочный пакет и бросить вызов творческим поощрительным деньгам

Инструкции по розыгрышу в конце статьи!

что такое отражение

Механизм отражения означает, что программа может получать свою собственную информацию во время выполнения, то есть динамически загружать класс и получать подробную информацию о классе во время работы программы, чтобы оперировать свойствами и методами класса или объекта. Суть в том, что после того, как JVM получает объект класса, она декомпилирует объект класса для получения различной информации об объекте. Отражение — одна из характеристик Java, механизм косвенного манипулирования целевыми объектами.

Основной класс отражения

Класс Class является основой реализации отражения.Чтобы понять отражение, вы должны сначала понять класс Class. Во время работы программы виртуальная машина поддерживает идентификатор типа, называемый временем выполнения, для всех объектов.Эта информация отслеживает полную структурную информацию о классе, к которому принадлежит каждый объект, включая имя пакета, имя класса, реализованный интерфейс, собственные методы и поля. , так далее. Доступ к этой информации можно получить через специальный класс Java, называемый классом Clas. Класс Class можно понимать как тип класса, объект класса называется объектом типа класса, а объект класса соответствует файлу .class, загруженному в JVM.

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;

    private static native void registerNatives();
    static {
        registerNatives();
    }
    
    ...
}    

Во-первых, JVM скомпилирует код в файл байт-кода .class, который затем будет загружен в память JVM загрузчиком классов, а объект класса класса будет создан и сохранен в куче (обратите внимание, что это не новый объект, а тип объекта класса). Прежде чем JVM создаст объект класса, она сначала проверит, загружен ли класс, найдет объект класса, соответствующий классу, и, если загружен, выделит для него память, а затем инициализирует его.

После загрузки класса в области методов кучи памяти создается объект класса.Этот объект содержит полную информацию о структуре класса.Через этот объект класса вы можете видеть структуру класса, как зеркало. Так назовите это: отражение. Дополнительные сведения о загрузке классов см. в предыдущей статье:Серия jvm: механизм загрузки классов

Основное использование отражения

Общие классы для механизмов отражения

Java.lang.Class; 

Java.lang.reflect.Constructor;  

Java.lang.reflect.Field;

Java.lang.reflect.Method; 

Java.lang.reflect.Modifier;

Отражение общих API

Объект.setAccessible(истина);

Сорт:

Получить общедоступные свойства: getField("имя свойства");

Получить частные свойства: getDeclaredField("имя свойства");

Получите общедоступный объект метода без параметров, указав имя метода: getMethod("имя метода", null);

Получить все объекты открытых методов: getMethods();

Получить все объекты метода: getDeclaredMethods();

Получите объект метода закрытого параметра, указав имя метода: getDeclaredMethod("имя метода", тип параметра метода...);

Вызов общедоступного параметризованного конструктора: getConstructor(тип параметра конструкции);

Вызвать конструктор закрытых параметров: getDeclaredConstructor (тип параметра конструкции);

Определите, является ли он экземпляром класса: isInstance(obj);

Поле:

Получить имя свойства: getName();

Получить тип свойства: getType();

Получить модификаторы свойства: getModifiers();

Установить значение свойства 1: класс создает экземпляр объекта Значение параметра, которое необходимо установить: set(obj,obj);

Метод:

Объект метода.invoke(объект экземпляра класса, массив параметров метода);//Выполнить метод

Конструктор:

NewInstance();//Получить экземпляр объекта класса, построив

См. код ниже:

public class Test(){
A a=new A();

Class c1=A.class;//任何一个类都有一个隐含的静态成员变量class

Class c2=a.getClass();//在已知类的对象的情况下通过getClass方法获取

Class c3 = null;

try {
    c3 = Class.forName("com.xxxx.A");//类的全称
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
}

class A{}

Отражение метода: getName

Метод getName может распечатать имя класса типа класса.

public class Test2 {
    public static void main(String[] args) {
        Class c1 = String.class;//String类的类类型
        Class c2 = void.class;
        System.out.println(c1.getName());
        System.out.println(c2.getName());
    }
}

отражение переменной-члена

public class TestUtil {
    public static void printFieldMessage(Object obj){
        Class c = obj.getClass();
        //Field[] fs = c.getFields();
    }

Информация обо всех общедоступных переменных-членах, полученная методом getFields(). В отражении метода есть общедоступные переменные-члены, а также есть информация для получения всех объявленных вами переменных-членов: Field[] fs = c.getDeclaredFields(), и тогда результаты, полученные путем обхода, следующие:

for (Field field : fs) {
//得到成员变量的类型的类类型
Class fieldType = field.getType();
String typeName = fieldType.getName();
//得到成员变量的名称
String fieldName = field.getName();
System.out.println(typeName+" "+fieldName);
}

Отражение конструктора

public static void Test(Object obj){
Class c = obj.getClass();
/*
* java.lang. Constructor中封装了构造函数的信息,它有两个方法:
* getConstructors()方法获取所有的public的构造函数
* getDeclaredConstructors()方法得到所有的自己声明的构造函数
*/
//Constructor[] cs = c.getConstructors();
Constructor[] cs = c.getDeclaredConstructors();
for (Constructor constructor : cs) {
System.out.print(constructor.getName()+"(");
//获取构造函数的参数列表->参数列表的类类型
Class[] paramTypes = constructor.getParameterTypes();
for (Class class1 : paramTypes) {
System.out.print(class1.getName()+",");
}
System.out.println(")");
}
}

Суммировать

Отражение не очень широко используется в реальном программировании, но многие проекты связаны с механизмами отражения, такими как: механизм динамического прокси, соединение JDBC с базой данных, Фреймворк Spring/Hibernate (фактически связанный с механизмом отражения из-за использования динамического прокси).

Инструкции по розыгрышу

1. Это событие официально поддерживается Nuggets, подробности можно посмотретьnuggets.capable/post/701221…

2. Вы можете принять участие, комментируя контент, связанный со статьей. Чем больше вы комментируете, тем больше у вас шансов выиграть приз.

3. Статьи этого месяца будут участвовать в лотерее, и все желающие могут принять участие!

4. В дополнение к официальной лотерее Наггетс, я также отправлю периферийные подарки (кружка и несколько значков Наггетс, кружка будет передана внимательным комментаторам, значки будут выбраны случайным образом, и количество будет увеличиваться в зависимости от количества комментариев).