Reflection API

Часто возникает необходимость во время исполнения java класса получить данные об этом же или другом классе. Это можно осуществить с помощью Reflection API.

Reflection API в Java используется для просмотра информации о классах, интерфейсах, методах, полях, конструкторах, аннотациях во время выполнения java программ.
При этом знать названия исследуемых элементов заранее не обязательно.

Все классы для работы с reflection расположены в пакете java.lang.reflect.

С помощью интерфейса Java Reflection API можно делать следующее:

  1. Определить класс объекта.
  2. Получить информацию о модификаторах класса, полях, методах, конструкторах и суперклассах.
  3. Выяснить, какие константы и методы принадлежат интерфейсу.
  4. Создать экземпляр класса, имя которого неизвестно до момента выполнения программы.
  5. Получить и установить значение свойства объекта.
  6. Вызвать метод объекта.
  7. Создать новый массив, размер и тип компонентов которого неизвестны до момента выполнения программ.

Как пример будем использовать класс приведенный ниже:

public class People 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

People people = new People();
Class myClass = people.getClass();

Самое простое, что обычно делается в динамическом программировании, — это получают объект типа java.lang.Class.

Если у нас есть экземпляр объекта Class мы можем получить всевозможную информацию об этом классе и даже осуществлять операции над ним. Вышеприведенный метод getClass() часто полезен тогда когда есть экземпляр объекта, но не известно какого класса этот экземпляр.

Если у нас есть класс, для которого в момент компиляции известен тип, то получить экземпляр класса ещё проще.

Class myClass = People.class;

Если имя класса не известно в момент компиляции, но становится известным во время выполнения программы, можно использовать метод forName(), чтобы получить объект Class.

Class c = Class.forName("com.mysql.jdbc.Driver");

 Получение пакета

Package p = clazz.getPackage();
System.out.println("package " + p.getName() + ";");

Выводим интерфейсы, которые реализует класс

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(" {");

Выводим поля класса

Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
   System.out.println("\t" + getModifiers(field.getModifiers()) + getType(field.getType()) + " " + field.getName() + ";");
}

Выводим методы, аннотации класса

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(") { }");
}
Урок создан: 09 января 2013 | Просмотров: 16562 | Автор: Александр Барчук | Правила перепечатки


Добавить комментарий

Добавить комментарий

Ваш e-mail не будет опубликован.

Комментарии:

  • 14 марта 2014 в 00:07

    Дмитрий

    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
    System.out.println(«\t» + getModifiers(field.getModifiers()) + getType(field.getType()) + » » + field.getName() + «;»);
    }

    Или я чего-то не знаю или тут опечатка)

    • 14 марта 2014 в 00:10

      Дмитрий

      Или если тут есть статический метод, то желательно указать, чтобы не путать никого)

    • 20 марта 2016 в 21:24

      Денис

      +1 Скорей всего тут что-то лишнее.
      Про getDeclaredFields не лишним будет сказать читателям, что он выбирает поля класса с любым модификатором, но в отличие от getFields (выбирает только публичные поля и мотоды) не выбирает поля класса, от которого унаследован тот, с которым работает пользователь!!!