Reflection API в Java используется для просмотра информации о классах, интерфейсах, методах, полях, конструкторах, аннотациях во время выполнения java программ.
package java.lang.reflect;
С помощью интерфейса Java Reflection API можно делать следующее:
- Определить класс объекта.
- Получить информацию о модификаторах класса, полях, методах, конструкторах и суперклассах.
- Выяснить, какие константы и методы принадлежат интерфейсу.
- Создать экземпляр класса, имя которого неизвестно до момента выполнения программы.
- Получить и установить значение свойства объекта.
- Вызвать метод объекта.
- Создать новый массив, размер и тип компонентов которого неизвестны до момента выполнения программ.
Для примера создадим сущность
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class User implements Serializable { private String name; private int age; public String getName() { return this.name; } public int getAge() { return this.age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.name = age; } @Deprecated protected static void method(String[] params) { } } |
Получение объекта типа Class
Самое простое, что обычно делается в динамическом программировании, — это получают объект типа java.lang.Class.
Если у нас есть экземпляр объекта Class мы можем получить всевозможную информацию об этом классе и даже осуществлять операции над ним. Вышеприведенный метод getClass() часто полезен тогда когда есть экземпляр объекта, но не известно какого класса этот экземпляр.
|
1 2 |
People people = new People(); Class myClass = people.getClass(); |
Если у нас есть класс, для которого в момент компиляции известен тип, то получить экземпляр класса ещё проще.
|
1 |
Class myClass = People.class; |
Если имя класса не известно в момент компиляции, но становится известным во время выполнения программы, можно использовать метод forName(), чтобы получить объект Class.
|
1 |
Class c = Class.forName("com.mysql.jdbc.Driver"); |
Получение имени класса
|
1 2 |
Class c = myObject.getClass(); String s = c.getName(); |
Объект типа String, возвращаемый методом getName(), будет содержать полностью уточненное имя класса, т.е. если типом объекта myObject будет Integer, то результат будет вида java.lang.Integer .
Получение пакета
|
1 2 |
Package p = clazz.getPackage(); System.out.println("package " + p.getName() + ";"); |
Получаем интерфейсы, которые реализует класс
|
1 2 3 4 5 6 |
Class[] interfaces = myClass.getInterfaces(); for (int i = 0, size = interfaces.length; i < size; i++) { System.out.print(i == 0 ? "implements " : ", "); System.out.print(interfaces[i].getSimpleName()); } System.out.println(" {"); |
Выводим поля класса
|
1 2 3 4 |
Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.println("\t" + getModifiers(field.getModifiers()) + getType(field.getType()) + " " + field.getName() + ";"); } |
Выводим методы, аннотации класса
|
1 2 3 4 5 6 7 8 9 10 11 12 |
Method[] methods = clazz.getDeclaredMethods(); for (Method m : methods) { Annotation[] annotations = m.getAnnotations(); System.out.print("\t"); for (Annotation a : annotations) System.out.print("@" + a.annotationType().getSimpleName() + " "); System.out.println(); System.out.print("\t" + getModifiers(m.getModifiers()) + getType(m.getReturnType()) + " " + m.getName() + "("); System.out.print(getParameters(m.getParameterTypes())); System.out.println(") { }"); } |