Reflection Java Advanced
2Georgiy KorneevJava Advanced / Reflection Содержание Введение Структура класса Массивы Загрузчики классов Параметры типов Proxy Заключение
3Georgiy KorneevJava Advanced / Reflection Reflection Библиотека, позволяющая оперировать информацией о типах во время выполнения Пакеты java.lang java.lang.reflect
Введение Часть 1
5Georgiy KorneevJava Advanced / Reflection Информация о типе Класс Class -- информация о типе Предоставляемая информация Структура класса Структура наследования Проверки времени выполнения …
6Georgiy KorneevJava Advanced / Reflection Получение информации о типе Во время исполнения object.getClass() Во время компиляции type.class Предопределенные Wrapper.TYPE
7Georgiy KorneevJava Advanced / Reflection Типы типов Для определения типов служат методы вида is*() АннотацияAnnotation МассивArray ПримитивныйPrimitive ПеречислениеEnum ИнтерфейсInterface Класс*Class Анонимный класс AnonymousClass Локальный класс LocalClass Класс-член MemberClass
8Georgiy KorneevJava Advanced / Reflection Общая информация о классе Имя класса getCanonicalName() – каноническое имя getName() – полное имя getSimpleName() – простое имя Структура классов getSuperClass() – предок getInterfaces() – реализуемые интерфейсы Модификаторы getModifiers() – модификаторы
9Georgiy KorneevJava Advanced / Reflection Место определения класса Методы получения места, в котором определен класс Тип классаМетод Верхнего уровняgetPackage() ВложенныйgetDeclaredClass() в конструкторgetEnclosingConstructor() в методgetEnclosingMethod()
10Georgiy KorneevJava Advanced / Reflection Приведение типов Определение возможности приведения isAssignableFrom(class) – класса isInstance(object) – объекта Приведение cast(object) – привести ссылку к типу
Структура класса Часть 2
12Georgiy KorneevJava Advanced / Reflection Информация о члене класса Интерфейс Member Методы getDeclaringClass() – класс, в котором определен getName() – имя члена getModifiers() – модификаторы
13Georgiy KorneevJava Advanced / Reflection Модификаторы Класс Modifiers КонстантаМетодМодификатор ABSTRACTisAbstractabstract FINALisFinalfinal INTERFACEisInterfaceinterface NATIVEisNativenative PRIVATEisPrivateprivate PROTECTEDisProtectedprotected PUBLICisPublicpublic STATICisStaticstatic STRICTisStrictstrictfp SYNCHRONIZEDisSynchronizedsynchronized TRANSIENTisTransienttransient VOLATILEisVolatilevolatile
14Georgiy KorneevJava Advanced / Reflection Поля Открытые getFields() – все поля getField(name) – конкретное поле Все getDeclaredFields() – все поля getDeclaredField(name) – конкретное поле Исключения NoSuchFieldException
15Georgiy KorneevJava Advanced / Reflection Свойства полей Класс Field Информация getName() – имя поля getType() – тип значения Чтение значения get(object) – ссылки get*(object) – значения примитивного типа Запись значения set(object, value) – ссылки set*(object, value) – значения примитивного типа
16Georgiy KorneevJava Advanced / Reflection Методы Открытые getMethods() – все методы getMethod(name, Class… parameters) – конкретный метод Все getDeclaredMethods() – все методы getDeclaredMethod(name, Class… parameters) – конкретный метод Исключения NoSuchMethodException
17Georgiy KorneevJava Advanced / Reflection Свойства методов Класс Method Сигнатура метода getName() – имя метода getParameterTypes() – параметры метода Другая информация getExceptionTypes() – возможные исключения getReturnType() – тип возвращаемого значения Вызов метода invoke(Object object, Object …args) – вызвать метод с указанными аргументами
18Georgiy KorneevJava Advanced / Reflection Конструкторы Открытые getConstructors() – все конструкторы getConstructor(Class… parameters) – конкретный конструктор Все getDeclaredConstructors() – все конструкторы getDeclaredConstructor(Class… parameters) – конкретный конструктор Исключения NoSuchMethodException
19Georgiy KorneevJava Advanced / Reflection Свойства конструкторов Класс Constructor Информация о конструкторе getParameterTypes() – параметры конструктора getExceptionTypes() – возможные исключения Создание объекта newInstance(Object … args) – создать новый объект class.newInstance() – создать новый объект используя конструктор по умолчанию
20Georgiy KorneevJava Advanced / Reflection Классы и интерфейсы Открытые getClasses() – все классы и интерфейсы Все getDeclaredClasses() – все классы и интерфейсы
21Georgiy KorneevJava Advanced / Reflection Доступ к закрытым членам По умолчанию доступ к закрытым членам запрещен IllegalAccessException Все члены extends AccessibleObject setAccessible(boolean) – запросить доступ isAccessible() – проверить доступ
22Georgiy KorneevJava Advanced / Reflection Пример: листинг класса Class c = …; for (Field m : c.getDeclaredFields()) { System.out.println(m); } for (Constructor m : c.getDeclaredConstructors()) { System.out.println(m); } for (Method m : c.getDeclaredMethods()) { System.out.println(m); }
23Georgiy KorneevJava Advanced / Reflection Пример: создание экземпляра // Получение класса Class clazz = Integer.class; // Получение конструктора Constructor c = clazz.getConstructor(int.class); // Создание экземпляра Integer i = (Integer) c.newInstance(100); // Проверка System.out.println(i);
Массивы Часть 3
25Georgiy KorneevJava Advanced / Reflection Операции с массивами Класс Array Создание массива заданного типа newInstance(Class, length) – линейного newInstance(Class, dims[]) – кубического Чтение значения из массива get(array, index) – ссылки get*(array, index) – значения примитивного типа Запись значения в массив set(array, index, value) – ссылки set*(array, index, value) – значения примитивного типа
26Georgiy KorneevJava Advanced / Reflection Массивы как типы Имя типа массива [имя_типа_элемента Методы isArray() – является ли массивом getComponentType() – тип элемента массива
27Georgiy KorneevJava Advanced / Reflection Имена для типов Имена классов типов в массиве кодируются специальным образом classLclass; booleanZ byteB charC doubleD floatF intI longJ shortS
Загрузчики классов Часть 4
29Georgiy KorneevJava Advanced / Reflection Загрузчики классов Позволяют загружать и определять новые классы Класс ClassLoader Методы loadClass(name, resolve?) – загружает класс по имени findLoadedClass(name) – найти уже загруженный класс resolveClass(class) – загружает библиотеки
30Georgiy KorneevJava Advanced / Reflection Дерево загрузчиков Загрузчики образуют дерево Загрузчики в разных ветвях могут загрузить разные классы с одним полным именем
31Georgiy KorneevJava Advanced / Reflection Дополнительные возможности Получения родителя getParent() Загрузка ресурсов URL getResource(String name) – определение местоположения ресурса по имени getResourceAsStream(String name) – чтение ресурса по имени
32Georgiy KorneevJava Advanced / Reflection Загрузчики и классы Получение загрузчика getClassLoader() – кто загрузил класс Thread.getContextClassLoader() – контекстный загрузчик Прямая загрузка класса Class.forName(name)
33Georgiy KorneevJava Advanced / Reflection Реализации загрузчиков Класс URLClassLoader Загружает классы из нескольких мест, заданных URL
34Georgiy KorneevJava Advanced / Reflection Пример: загрузка класса URL jar = new URL("file://."); className = "Test"; ClassLoader cl = new URLClassLoader(new URL[]{jar}); Class c = cl.loadClass(className); Method m = c.getMethod("main", String[].class); m.invoke(null, (Object) new String[]{"hello"});
Параметры типов Часть 5
36Georgiy KorneevJava Advanced / Reflection Информация о параметрах типов (ПТ) Информация о конкретных параметрах типов стирается Информация о зависимостях типов сохраняется
37Georgiy KorneevJava Advanced / Reflection Получение информация о ПТ Для классов getGenericSuperclass() getGenericInterfaces() Для методов и конструкторов getGenericParameterTypes() getGenericReturnType() getGenericExceptionTypes() Для полей getGenericType()
38Georgiy KorneevJava Advanced / Reflection Представление информации о ПТ Интерфейс Type КлассыClass Параметризованный класс ParameterizedType Переменная типаTypeVariable WildcardWildcardType МассивыGenericArrayType
39Georgiy KorneevJava Advanced / Reflection Параметризованные классы Пример: Collection Интерфейс ParameterizedType getRawType() – не параметризованный тип getActualTypeArguments() – реальные аргументы типа
40Georgiy KorneevJava Advanced / Reflection Переменные типа Пример: T Получение getTypeParameters() Интерфейс TypeVariable getName() – имя переменной getBounds() – верхние границы getGenericDeclaration() – кто объявил
41Georgiy KorneevJava Advanced / Reflection Wildcards Пример: ? super HashSet extends Collection Интерфейс Wildcard getUpperBounds() – Верхние границы getLowerBounds() – Нижние границы
42Georgiy KorneevJava Advanced / Reflection Массивы Тип элемента – переменная типа Пример: T[] Тип элемента – параметризованный тип Пример: Set [] Интерфейс GenericArrayType getGenericComponentType() – тип элемента
Proxy Часть 6
44Georgiy KorneevJava Advanced / Reflection Proxy Механизм, позволяющий создавать фиктивные классы, реализующие требуемые интерфейсы Класс Proxy
45Georgiy KorneevJava Advanced / Reflection Класс InvocationHandler Ему делегируются вызовы, совершенные для Proxy Методы invoke(Object proxy, Method method, Object[] args) – уведомляет о вызове метода
46Georgiy KorneevJava Advanced / Reflection Методы Proxy Создание экземпляра Proxy newProxyInstance(ClassLoader, Class[] interfaces, InvocationHandler) Получение класса Proxy getProxyClass(ClassLoader, Class[] interfaces) Проверка класса isProxyClass(Class)
47Georgiy KorneevJava Advanced / Reflection Пример: профайлер (1) Класс public class Profiler implements InvocationHandler { // Экземпляр Proxy private final Object instance; // Реальная реализация private final Object impl; … }
48Georgiy KorneevJava Advanced / Reflection Пример: профайлер (2) Конструктор public Profiler(Class[] i8s, Object impl) { this.impl = impl; instance = Proxy.newProxyInstance(null, i8s, this); } Создание экземпляра public Object getInstance() { return instance; }
49Georgiy KorneevJava Advanced / Reflection Пример: профайлер (3) Основной метод public Object invoke( Object proxy, Method method, Object[] args ) throws IllegalAccessException, InvocationTargetException { System.out.println("Calling " + method + " on " + impl); return method.invoke(impl, args); }
50Georgiy KorneevJava Advanced / Reflection Пример: профайлер (4) Применение public static void main(String[] args) { Integer i1 = new Integer(3); Profiler profiler = new Profiler( new Class[]{Comparable.class}, i1); Comparable i2 = (Comparable) profiler.getInstance(); System.out.println(i2.compareTo(i1)); }
Заключение Часть 7
52Georgiy KorneevJava Advanced / Reflection Выводы Reflection позволяет Анализировать классы по время исполнения Загружать классы по имени Создавать экземпляры классов по имени Вызывать метод классов по имени Оперировать значениями полей по имени Создавать и оперировать с массивами по типу элемента Создавать proxy для интерфейсов
53Georgiy KorneevJava Advanced / Reflection Ссылки Reflection (Guide) // ndex.html ndex.html Reflection API Code Samples // Using Java Reflection // Reflection/index.html Reflection/index.html The Reflection API (tutorial) // html html
54Georgiy KorneevJava Advanced / Reflection Вопросы