Назад Зміст Вперед

3.3. Клас java.lang.Class. Основи рефлексії

Часто виникає необхідність під час виконання java класу отримати дані про цей же або інший клас. Це можна здійснити за допомогою Reflection API.

Reflection API в Java використовується для перегляду інформації про класи, інтерфейси, методи, поля, конструктори, анотації під час виконання java програм. При цьому знати назви досліджуваних елементів заздалегідь не обов'язково. Усі класи для роботи з reflection розташовані в пакеті java.lang.reflect.

За допомогою інтерфейсу Java Reflection API можна робити наступне:
  • Визначити клас об'єкту.
  • Отримати інформацію про модифікатори класу, поля, методи, конструктори і суперкласи.
  • З'ясувати, які константи і методи належать інтерфейсу.
  • Створити екземпляр класу, ім'я якого невідоме до моменту виконання програми.
  • Отримати і встановити значення властивості об'єкту.
  • Викликати метод об'єкту.
  • Створити новий масив, розмір і тип компонентів якого невідомі до моменту виконання програм.
Приклад:
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 c = Class.forName("com.mysql.jdbc.Driver");

Отримання пакету
Package p = class.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 = class.getDeclaredFields();
for (Field field : fields) {
   System.out.println("\t" + getModifiers(field.getModifiers()) +
getType(field.getType()) + " " + field.getName() + ";");
}

Виводимо методи, анотації класу
Method[] methods = class.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(") { }");
}

.