Reflection API

Intro

Problem

  • How research class?

  • How create classes in runtime?

Solution

Reflection API

Reflection juggling

Reflection API

Reflection API

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

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

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

Structure

Reflection Structure

Класс Class

Класс Class

  • С помощью Class можно осуществить:

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

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

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

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

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

  • Получение класса по объекту:

Class c1 = object.getClass();
  • Получение класса через литерал:

Class c2 = String[].class;
  • Загрузка класса по имени:

Class c3 = Class.forName("java.lang.Integer");

Class loading

  • Можно загрузить класс из файловой системы или сети в runtime:

URL jarFileURL = new URL ("file://interface-impl.jar");
ClassLoader classLoader =
        new URLClassLoader(new URL [] { jarFileURL });
Class c4 = classLoader.loadClass("by.rakovets.InterfaceImpl");

Custom Class Loader

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

    private byte [] getClassData(String name) {
        // code that returns contents of java class (file)
    }
}

Методы для Class

Получение имени

Methodint[]Object[]Foo.Bar

getSimpleName()

int[]

Object[]

Bar

getCanonicalName()

int[]

java.lang.Object[]

Foo.Bar

getName()

[I

Ljava.jang.Object;

Foo$Bar

Уточнение типа

  • isArray(): boolean

  • isInterface(): boolean

  • isPrimitive(): boolean

Место в иерархии наследования

  • getSuperclass(): Class<?>

  • getInterfaces(): Class<?>[]

Пакет и модификаторы

  • getPackage(): Package - возвращает пакет.

  • getModifiers(): int - возвращает модификаторы класса.

Constructors for Class

  • Not private constructor

    • getConstructor(Class…​ types): Constructor

    • getConstructors(): Constructors<?>[]

  • All constructors:

    • getDeclaredConstructor(Class…​ types): Constructor

    • getDeclaredConstructors(): Constructors<?>[]

Example

Constructor constructor = clazz.getConstructor(String.class);
Object instance = constructor.newInstance(" Hello World !");

Methods for Class

  • Открытые методы, в том числе унаследованные:

    • getMethod(String name, Class…​ types): Method

    • getMethods(): Method[]

  • Все методы, но только из текущего класса:

    • getDeclaredMethod(String name, Class…​ types): Method

    • getDeclaredMethods(): Method[]

Example

Method method = clazz.getMethod ("doSomething", int.class);
Object result = method.invoke(instance, 42);

Fields for Class

  • Открытые поля, в том числе унаследованные:

    • getField(String name): Field

    • getFields(): Field[]

  • Все поля, но только из текущего класса:

    • getDeclaredField(String name): Field

    • getDeclaredFields(): Field[]

Annotations

  • getAnnotations(): Annotation[]

  • getDeclaredAnnotations(): Annotation[]

Example

Annotation[] annotations = studentClass.getAnnotations();
Arrays.stream(annotations)
        .map(a -> a.annotationType().getCanonicalName())
        .forEach(System.out::println);