Transcript
Page 1: Java, осень 2014: Java-классы: взгляд изнутри

Java-классы: взгляд изнутри

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

27 октября 2014

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 1 / 29

Page 2: Java, осень 2014: Java-классы: взгляд изнутри

1 Reflection API

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

3 Байткод Java

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 2 / 29

Page 3: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 3 / 29

Page 4: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

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

Пакет java.lang.reflect

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 4 / 29

Page 5: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

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

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

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 5 / 29

Page 6: Java, осень 2014: Java-классы: взгляд изнутри

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

Page 7: Java, осень 2014: Java-классы: взгляд изнутри

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

Page 8: Java, осень 2014: Java-классы: взгляд изнутри

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

Page 9: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

Типы классов

boolean isPrimitive()

boolean isArray()

boolean isEnum()

boolean isInterface()

boolean isAnnotation()

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 9 / 29

Page 10: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

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

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 10 / 29

Page 11: Java, осень 2014: Java-классы: взгляд изнутри

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

Page 12: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

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

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 12 / 29

Page 13: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

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

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 13 / 29

Page 14: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

Методы

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 14 / 29

Page 15: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

Вызов метода

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 15 / 29

Page 16: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

Поля

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 16 / 29

Page 17: Java, осень 2014: Java-классы: взгляд изнутри

Reflection API

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

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

Object value = field.get(instance );

field.set(instance , null);

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 17 / 29

Page 18: Java, осень 2014: Java-классы: взгляд изнутри

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

Page 19: Java, осень 2014: Java-классы: взгляд изнутри

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 19 / 29

Page 20: Java, осень 2014: Java-классы: взгляд изнутри

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

Инструмент JOL

Демо

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 20 / 29

Page 21: Java, осень 2014: Java-классы: взгляд изнутри

Байткод Java

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 21 / 29

Page 22: Java, осень 2014: Java-классы: взгляд изнутри

Байткод Java

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 22 / 29

Page 23: Java, осень 2014: Java-классы: взгляд изнутри

Байткод 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

Page 24: Java, осень 2014: Java-классы: взгляд изнутри

Байткод Java

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 24 / 29

Page 25: Java, осень 2014: Java-классы: взгляд изнутри

Байткод Java

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

2 + 3 · 4

2 3 4 · +

iconst_2iconst_3iconst_4imuliadd

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 25 / 29

Page 26: Java, осень 2014: Java-классы: взгляд изнутри

Байткод 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

Page 27: Java, осень 2014: Java-классы: взгляд изнутри

Байткод Java

Библиотека ASM

Демо

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 27 / 29

Page 28: Java, осень 2014: Java-классы: взгляд изнутри

Байткод Java

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

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

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

Enterprise фреймворки

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 28 / 29

Page 29: Java, осень 2014: Java-классы: взгляд изнутри

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

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

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

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

Алексей Владыкин Java-классы: взгляд изнутри 27 октября 2014 29 / 29


Recommended