Java-классы: взгляд изнутри
Алексей Владыкин
27 октября 2014
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 1 / 29
1 Reflection API
2 Расположение объекта в памяти
3 Байткод Java
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 2 / 29
Reflection API
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 3 / 29
Reflection API
Reflection API — программный интерфейс для полученияинформации об объектах и классах во время исполненияпрограммы
Пакет java.lang.reflect
Для каждого типа, в том числе примитивного, можно получитьописывающий его экземпляр класса Class
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 4 / 29
Reflection API
Возможности Reflection API
Получение списка конструкторов, методов и полей класса
Создание экземпляров класса
Вызов методов и чтение/запись полей, в том числе закрытых
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 5 / 29
Reflection API
Как получить Class
Получение класса по объекту:Class c1 = object.getClass();
Получение класса через литерал:Class c2 = String[].class;Class c3 = int.class;
Загрузка класса по имени:Class c4 = Class.forName("java.lang.Integer");
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 6 / 29
Reflection API
Как загрузить класс с диска
URL jarFileURL =Paths.get("library.jar").toUri (). toURL ();
ClassLoader classLoader =new URLClassLoader(new URL[] {jarFileURL });
Class clazz = classLoader.loadClass("ru.csc.java2014.DemoClass");
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 7 / 29
Reflection API
Имя класса
int[] Object[] Foo.BargetName() [I [Ljava.lang.Object; Foo$BargetCanonicalName() int[] java.lang.Object[] Foo.BargetSimpleName() int[] Object[] Bar
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 8 / 29
Reflection API
Типы классов
boolean isPrimitive()
boolean isArray()
boolean isEnum()
boolean isInterface()
boolean isAnnotation()
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 9 / 29
Reflection API
Специфика массивов
if (clazz.isArray ()) {System.out.println(
"Array of " + c.getComponentType ());}
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 10 / 29
Reflection API
Специфика enum
if (clazz.isEnum ()) {System.out.println("Enum of:");for (Object e : clazz.getEnumConstants ()) {
System.out.println(e);}
}
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 11 / 29
Reflection API
Конструкторы
Открытые конструкторы:Constructor getConstructor(Class... types)Constructor[] getConstructors()
Все конструкторы:Constructor getDeclaredConstructor(Class... types)Constructor[] getDeclaredConstructors()
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 12 / 29
Reflection API
Вызов конструктора
Constructor constructor =clazz.getConstructor(String.class);
Object instance =constructor.newInstance("Hello World!");
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 13 / 29
Reflection API
Методы
Открытые методы, в том числе унаследованные:Method getMethod(String name, Class... types)Method[] getMethods()
Все методы, но только из текущего класса:Method getDeclaredMethod(String name, Class... types)Method[] getDeclaredMethods()
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 14 / 29
Reflection API
Вызов метода
Method method =clazz.getMethod("doSomething", int.class);
Object result =method.invoke(instance , 42);
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 15 / 29
Reflection API
Поля
Открытые поля, в том числе унаследованные:Field getField(String name)Field[] getFields()
Все поля, но только из текущего класса:Field getDeclaredField(String name)Field[] getDeclaredFields()
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 16 / 29
Reflection API
Чтение/запись поля
Field field = clazz.getDeclaredField("x");field.setAccessible(true);
Object value = field.get(instance );
field.set(instance , null);
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 17 / 29
Reflection API
Аннотации
Version version =clazz.getAnnotation(Version.class);
if (version != null) {System.out.println(version.value ());System.out.println(version.date ());
}
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 18 / 29
Расположение объекта в памяти
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 19 / 29
Расположение объекта в памяти
Инструмент JOL
Демо
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 20 / 29
Байткод Java
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 21 / 29
Байткод Java
Структура .class файла
Заголовок (CAFEBABE, версия формата)Constant pool (числа, строки, имена классов, полей и методов)Объявление класса (модификаторы, имя класса, имя суперкласса,имена реализуемых интерфейсов)Поля классаМетоды классаАтрибуты класса (аннотации, debug info, . . . )javap -v -p ru.csc.java2014.DemoClass
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 22 / 29
Байткод Java
Имена в байткоде
Никаких импортов, все имена полныеИмена классов: java/lang/StringИмена типов:
B, C, D, F, I, J, S, ZLjava/lang/Object;[[I
Имена методов:<init> ()V<clinit> ()Vequals (Ljava/lang/Object;)ZtoString ()Ljava/lang/String;sort ([III)V
Имена параметров и локальных переменных отсутствуют
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 23 / 29
Байткод Java
Исполняемый код
Состоит из простых инструкций (около 200)Работает в рамках одного фрейма стека вызововИмеет локальный стек заданного размера, где и выполняет всевычисленияМожет обращаться к полям и методам объектов, а также к своимаргументам и локальным переменным
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 24 / 29
Байткод Java
Стековая арифметика
2 + 3 · 4
2 3 4 · +
iconst_2iconst_3iconst_4imuliadd
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 25 / 29
Байткод Java
Основные инструкции
Значения в стеке и локальных переменных:*const*, ldc*, *load*, *store*Арифметика:*mul, *div, *add, *subРабота с объектами:new, getfield, putfield, getstatic, putstaticВызовы методов:invokestatic, invokevirtual, invokespecial, *returnПроверки и переходы:*cmp, if*, goto*
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 26 / 29
Байткод Java
Библиотека ASM
Демо
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 27 / 29
Байткод Java
Зачем работать с байткодом?
Альтернативные языки для JVM
Статический и динамический анализ кода
Enterprise фреймворки
Библиотеки для mock’ов
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 28 / 29
Что сегодня узнали
Что такое Reflection API и какие возможности он предоставляет
Как узнать, сколько места занимает объект и как расположеныего поля в памяти
Как устроен байткод Java, и что это дает
Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 29 / 29