32
Стандартная библиотека Java: Reflection API Алексей Владыкин 28 октября 2013 Алексей Владыкин Reflection API 28 октября 2013 1 / 32

2013 10 28_java_lecture_08

Embed Size (px)

Citation preview

Page 1: 2013 10 28_java_lecture_08

Стандартная библиотека Java:Reflection API

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

28 октября 2013

Алексей Владыкин Reflection API 28 октября 2013 1 / 32

Page 2: 2013 10 28_java_lecture_08

1 Аннотации

2 Reflection API

Алексей Владыкин Reflection API 28 октября 2013 2 / 32

Page 3: 2013 10 28_java_lecture_08

Аннотации

Алексей Владыкин Reflection API 28 октября 2013 3 / 32

Page 4: 2013 10 28_java_lecture_08

Аннотации

Аннотации — это метаданные, сопровождающие исполняемый код

В отличие от Javadoc, являются машиночитаемыми и могут бытьдоступны во время исполнения

Примеры аннотаций:@Override@Deprecated@SuppressWarnings

Алексей Владыкин Reflection API 28 октября 2013 4 / 32

Page 5: 2013 10 28_java_lecture_08

Аннотации

Что можно аннотировать

ПакетТип (класс, интерфейс, enum)Поле классаМетод, конструкторПараметр методаЛокальная переменная

Алексей Владыкин Reflection API 28 октября 2013 5 / 32

Page 6: 2013 10 28_java_lecture_08

Аннотации

Создание аннотации

package ru.compscicenter.java2013;

import java.lang.annotation .*;

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface Version {

String value ();String date() default "";

}

Аннотация является особым видом интерфейса:extends Annotation

Алексей Владыкин Reflection API 28 октября 2013 6 / 32

Page 7: 2013 10 28_java_lecture_08

Аннотации

Использование аннотации

package ru.compscicenter.java2013;

@Version(value = "3.14", date = "01.01.2011")public class Component {

// ...}

Экземпляр аннотации является объектом,у которого можно вызвать методы value() и date()

Нельзя создать экземпляр аннотации вызовом new

Можно написать класс, реализующий интерфейс аннотации

Алексей Владыкин Reflection API 28 октября 2013 7 / 32

Page 8: 2013 10 28_java_lecture_08

Аннотации

Когда можно использовать аннотации

Во время компиляции(Annotation Processing API)

После компиляции, в class-файлах(например, статический анализ FindBugs)

Во время исполнения программы(Reflection API)

Алексей Владыкин Reflection API 28 октября 2013 8 / 32

Page 9: 2013 10 28_java_lecture_08

Аннотации

Алексей Владыкин Reflection API 28 октября 2013 9 / 32

Page 10: 2013 10 28_java_lecture_08

Аннотации

Пример использования аннотаций: JSR305

import javax.annotation .*;

public class JSR305Demo {

@Nullablepublic Object getCurrentObject (){ /*...*/}

@Nonnullpublic Object newObject (){ /*...*/ }

}

Алексей Владыкин Reflection API 28 октября 2013 10 / 32

Page 11: 2013 10 28_java_lecture_08

Аннотации

Пример использования аннотаций: JAXB

import javax.xml.bind.annotation .*;

@XmlRootElement(name = "Person")@XmlType(propOrder = {"firstName", "lastName"})public class Person {

@XmlElement(name = "FirstName")public String firstName;

@XmlElement(name = "LastName")public String lastName;

}

Алексей Владыкин Reflection API 28 октября 2013 11 / 32

Page 12: 2013 10 28_java_lecture_08

Аннотации

Пример использования аннотаций: JAXB

Person p = new Person ();p.firstName = "Ivan";p.lastName = "Ivanov";

JAXBContext jaxbContext =JAXBContext.newInstance(Person.class );

Marshaller jaxbMarshaller =jaxbContext.createMarshaller ();

jaxbMarshaller.marshal(p, System.out);

Алексей Владыкин Reflection API 28 октября 2013 12 / 32

Page 13: 2013 10 28_java_lecture_08

Аннотации

Пример использования аннотаций: JPA

import javax.persistence .*;

@Entitypublic class Person {

@Id @Columnpublic long id;

@Column(name = "first_name")public String firstName;

@Column(name = "last_name")public String lastName;

}

Алексей Владыкин Reflection API 28 октября 2013 13 / 32

Page 14: 2013 10 28_java_lecture_08

Аннотации

Пример использования аннотаций: JPA

EntityManager entityManager = getEntityManager ();

Person p = entityManager.find(Person.class , 333);p.firstName = "Ivan";p.lastName = "Ivanov";

entityManager.merge(p);

Алексей Владыкин Reflection API 28 октября 2013 14 / 32

Page 15: 2013 10 28_java_lecture_08

Reflection API

Алексей Владыкин Reflection API 28 октября 2013 15 / 32

Page 16: 2013 10 28_java_lecture_08

Reflection API

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

Центральный класс — java.lang.reflect.Class

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

Алексей Владыкин Reflection API 28 октября 2013 16 / 32

Page 17: 2013 10 28_java_lecture_08

Reflection API

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

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

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

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

Но нельзя получить содержимое метода

Алексей Владыкин Reflection API 28 октября 2013 17 / 32

Page 18: 2013 10 28_java_lecture_08

Reflection API

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

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

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

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

Алексей Владыкин Reflection API 28 октября 2013 18 / 32

Page 19: 2013 10 28_java_lecture_08

Reflection API

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

URL jarFileURL = new URL("file :// electro.jar");

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

Class c4 = classLoader.loadClass("ElectroSolver");

Алексей Владыкин Reflection API 28 октября 2013 19 / 32

Page 20: 2013 10 28_java_lecture_08

Reflection API

Как создать класс на лету

public class MyClassLoader extends ClassLoader {

protected Class <?> findClass(String name) {byte[] b = getClassData(name);return defineClass(name , b, 0, b.length );

}

private byte[] getClassData(String name) {// skip

}}

Алексей Владыкин Reflection API 28 октября 2013 20 / 32

Page 21: 2013 10 28_java_lecture_08

Reflection API

Имя класса

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

Алексей Владыкин Reflection API 28 октября 2013 21 / 32

Page 22: 2013 10 28_java_lecture_08

Reflection API

Типы классов

boolean isPrimitive()

boolean isInterface()

boolean isAnnotation()

Class getSuperclass()

Class[] getInterfaces()

Алексей Владыкин Reflection API 28 октября 2013 22 / 32

Page 23: 2013 10 28_java_lecture_08

Reflection API

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

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

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

Алексей Владыкин Reflection API 28 октября 2013 23 / 32

Page 24: 2013 10 28_java_lecture_08

Reflection API

Специфика enum

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

System.out.println(e);}

}

Алексей Владыкин Reflection API 28 октября 2013 24 / 32

Page 25: 2013 10 28_java_lecture_08

Reflection API

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

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

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

Алексей Владыкин Reflection API 28 октября 2013 25 / 32

Page 26: 2013 10 28_java_lecture_08

Reflection API

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

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

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

Алексей Владыкин Reflection API 28 октября 2013 26 / 32

Page 27: 2013 10 28_java_lecture_08

Reflection API

Методы

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

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

Алексей Владыкин Reflection API 28 октября 2013 27 / 32

Page 28: 2013 10 28_java_lecture_08

Reflection API

Вызов метода

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

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

Алексей Владыкин Reflection API 28 октября 2013 28 / 32

Page 29: 2013 10 28_java_lecture_08

Reflection API

Поля

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

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

Алексей Владыкин Reflection API 28 октября 2013 29 / 32

Page 30: 2013 10 28_java_lecture_08

Reflection API

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

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

Object value = field.get(instance );

field.set(instance , null);

Алексей Владыкин Reflection API 28 октября 2013 30 / 32

Page 31: 2013 10 28_java_lecture_08

Reflection API

Аннотации

Version version =clazz.getAnnotation(Version.class);

String versionNumber = version.value ();String versionDate = version.date ();

Алексей Владыкин Reflection API 28 октября 2013 31 / 32

Page 32: 2013 10 28_java_lecture_08

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

Что такое аннотации в Java и как их можно использовать

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

Алексей Владыкин Reflection API 28 октября 2013 32 / 32