Программирование на java, осень 2016: java-классы под капотом

28
Java-классы под капотом Алексей Владыкин 7 ноября 2016 Алексей Владыкин Java-классы под капотом 7 ноября 2016 1 / 28

Upload: cs-center

Post on 16-Jan-2017

192 views

Category:

Documents


0 download

TRANSCRIPT

Java-классы под капотом

Алексей Владыкин

7 ноября 2016

Алексей Владыкин Java-классы под капотом 7 ноября 2016 1 / 28

1 Reflection API

2 Расположение объекта в памяти

3 Байткод Java

Алексей Владыкин Java-классы под капотом 7 ноября 2016 2 / 28

Reflection API

Алексей Владыкин Java-классы под капотом 7 ноября 2016 3 / 28

Reflection API

Reflection API — программный интерфейс для полученияинформации об объектах и классах во время исполненияпрограммы

java.lang.Class и java.lang.reflect.*

Для каждого типа, в том числе примитивного, можно получитьописывающий его экземпляр класса Class

Алексей Владыкин Java-классы под капотом 7 ноября 2016 4 / 28

Reflection API

Возможности Reflection API

Получение списка конструкторов, методов и полей класса

Создание экземпляров класса

Вызов методов и чтение/запись полей, в том числе закрытых

Алексей Владыкин Java-классы под капотом 7 ноября 2016 5 / 28

Reflection API

Как получить Class

Получение класса по объекту:Class c1 = object.getClass();

Получение класса через литерал:Class c2 = String[].class;Class c3 = int.class;

Загрузка класса по имени:Class c4 = Class.forName("java.lang.Integer");

Алексей Владыкин Java-классы под капотом 7 ноября 2016 6 / 28

Reflection API

Как загрузить класс с диска

URL jarFileURL =Paths.get("library.jar").toUri (). toURL ();

ClassLoader classLoader =new URLClassLoader(new URL[] {jarFileURL });

Class clazz = classLoader.loadClass("ru.csc.java201.DemoClass");

Алексей Владыкин Java-классы под капотом 7 ноября 2016 7 / 28

Reflection API

Имя класса

int[] Object[] Foo.BargetName() [I [Ljava.lang.Object; Foo$BargetCanonicalName() int[] java.lang.Object[] Foo.BargetSimpleName() int[] Object[] Bar

Алексей Владыкин Java-классы под капотом 7 ноября 2016 8 / 28

Reflection API

Типы классов

boolean isPrimitive()

boolean isArray()

boolean isEnum()

boolean isInterface()

boolean isAnnotation()

Алексей Владыкин Java-классы под капотом 7 ноября 2016 9 / 28

Reflection API

Специфика массивов

if (clazz.isArray ()) {System.out.println(

"Array of " + c.getComponentType ());}

Алексей Владыкин Java-классы под капотом 7 ноября 2016 10 / 28

Reflection API

Специфика enum

if (clazz.isEnum ()) {System.out.println("Enum of:");for (Object e : clazz.getEnumConstants ()) {

System.out.println(e);}

}

Алексей Владыкин Java-классы под капотом 7 ноября 2016 11 / 28

Reflection API

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

Открытые конструкторы:Constructor getConstructor(Class... types)Constructor[] getConstructors()

Все конструкторы:Constructor getDeclaredConstructor(Class... types)Constructor[] getDeclaredConstructors()

Алексей Владыкин Java-классы под капотом 7 ноября 2016 12 / 28

Reflection API

Вызов конструктора

Constructor constructor =clazz.getConstructor(String.class);

Object instance =constructor.newInstance("Hello World!");

Алексей Владыкин Java-классы под капотом 7 ноября 2016 13 / 28

Reflection API

Методы

Открытые методы, в том числе унаследованные:Method getMethod(String name, Class... types)Method[] getMethods()

Все методы, но только из текущего класса:Method getDeclaredMethod(String name, Class... types)Method[] getDeclaredMethods()

Алексей Владыкин Java-классы под капотом 7 ноября 2016 14 / 28

Reflection API

Вызов метода

Method method =clazz.getMethod("doSomething", int.class);

Object result =method.invoke(instance , 42);

Алексей Владыкин Java-классы под капотом 7 ноября 2016 15 / 28

Reflection API

Поля

Открытые поля, в том числе унаследованные:Field getField(String name)Field[] getFields()

Все поля, но только из текущего класса:Field getDeclaredField(String name)Field[] getDeclaredFields()

Алексей Владыкин Java-классы под капотом 7 ноября 2016 16 / 28

Reflection API

Чтение/запись поля

Field field = clazz.getDeclaredField("x");field.setAccessible(true);

Object value = field.get(instance );

field.set(instance , null);

Алексей Владыкин Java-классы под капотом 7 ноября 2016 17 / 28

Расположение объекта в памяти

Алексей Владыкин Java-классы под капотом 7 ноября 2016 18 / 28

Расположение объекта в памяти

Инструмент JOL

Демо

Алексей Владыкин Java-классы под капотом 7 ноября 2016 19 / 28

Байткод Java

Алексей Владыкин Java-классы под капотом 7 ноября 2016 20 / 28

Байткод Java

Структура .class файла

Заголовок (CAFEBABE, версия формата)Constant pool (числа, строки, имена классов, полей и методов)Объявление класса (модификаторы, имя класса, имя суперкласса,имена реализуемых интерфейсов)Поля классаМетоды классаАтрибуты класса (аннотации, debug info, . . . )javap -v -p ru.csc.java.DemoClass

Алексей Владыкин Java-классы под капотом 7 ноября 2016 21 / 28

Байткод 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-классы под капотом 7 ноября 2016 22 / 28

Байткод Java

Исполняемый код

Состоит из простых инструкций (около 200)Работает в рамках одного фрейма стека вызововИмеет локальный стек заданного размера, где и выполняет всевычисленияМожет обращаться к полям и методам объектов, а также к своимаргументам и локальным переменным

Алексей Владыкин Java-классы под капотом 7 ноября 2016 23 / 28

Байткод Java

Стековая арифметика

2 + 3 · 4

2 3 4 · +

iconst_2iconst_3iconst_4imuliadd

Алексей Владыкин Java-классы под капотом 7 ноября 2016 24 / 28

Байткод Java

Основные инструкции

Значения в стеке и локальных переменных:*const*, ldc*, *load*, *store*Арифметика:*mul, *div, *add, *subРабота с объектами:new, getfield, putfield, getstatic, putstaticВызовы методов:invokestatic, invokevirtual, invokespecial, *returnПроверки и переходы:*cmp, if*, goto*

Алексей Владыкин Java-классы под капотом 7 ноября 2016 25 / 28

Байткод Java

Библиотека ASM

Демо

Алексей Владыкин Java-классы под капотом 7 ноября 2016 26 / 28

Байткод Java

Зачем работать с байткодом?

Альтернативные языки для JVM

Статический и динамический анализ кода

Enterprise фреймворки

Библиотеки для mock’ов

Алексей Владыкин Java-классы под капотом 7 ноября 2016 27 / 28

Что сегодня узнали

Что такое Reflection API и какие возможности он предоставляет

Как узнать, сколько места занимает объект и как расположеныего поля в памяти

Как устроен байткод Java, и что это дает

Алексей Владыкин Java-классы под капотом 7 ноября 2016 28 / 28