— Привіт, Аміго!

А тепер найцікавіше. Ми познайомимося з класом Class та трохи з Reflection.
Як ти вже, напевно, встиг зрозуміти, в Java все є об'єктом. А що потрібне для об'єкта? Що має кожен об'єкт і визначає саму його суть?

— Клас об'єкта!

— Правильно! Молодець. Кожен об'єкт має клас. Але повернімося до об'єктів. Деякі об'єкти повністю містять якусь сутність, інші ж просто допомагають нею керувати.

До інших можна віднести FileOutputStream або Thread. Коли ти створюєш об'єкт Thread, новий потік не створюється. Його створює Java-машина після виклику методу start(). Цей об'єкт просто допомагає керувати процесом.

Так само й FileOutputStream: файл зберігається на диску, і його зберіганням та доступом до нього керує ОС. Але ми можемо взаємодіяти з ним через об'єкти типу File, знову ж таки за допомогою Java-машини.

— Так, я це зрозумів вже.

— Так ось, для взаємодії з класами є спеціальний клас, і називається він — Class.

— Неважко було здогадатися.

— Ага. Щоразу, коли Java-машина завантажує до пам'яті новий клас, вона створює об'єкт типу Class, з якого можна отримати деяку інформацію про завантажений клас.

До кожного класу та об'єкту прив'язаний такий «об'єкт класу».

Приклад Опис
Class clazz = Integer.class;
Отримання «об'єкт класу» у класу Integer.
Class clazz = int.class;
Отримання «об'єкт класу» у класу int.
Class clazz = "123".getClass();
Отримання «об'єкт класу» у об'єкту типу String.
Class clazz = new Object().getClass();
Отримання «об'єкт класу» у об'єкту типу Object.

— Оце так цікаво.

А чому ти пишеш clazz, а не class?

— А ти пам'ятаєш, що слово class – це ключове слово в Java і використовувати його для найменування змінних не можна?

— Так, я знаю, знаю. Тільки забув.

— Ти десь вже використовував об'єкт Class?

— Так, ми використовували його, коли писали свою реалізацію методу equals.

— Так, можна порівняти, чи однакові в об'єктів класи, якщо скористатися методом getClass().

— А що можна робити з цим об'єктом?

— Ну, багато чого:

Код на Java Опис
Class s = int.class;
String name = s.getName();
Отримати ім'я класу.
Class s = Class.forName("java.lang.String");
Отримати клас за іменем.
Object o1 = String.valueOf(1);
Object o2 = 123 + "T";
o1.getClass() == o2.getClass();
Порівняти класи в об'єктів.

— Цікаво, але не так круто, як я думав.

— Хочеш, щоб було круто? Є ще Reflection. Reflection – це дуже круто.

— А що таке Reflection?

Reflection – це здатність класу отримати інформацію про самого себе. У Java є спеціальні класи: Field – поле, Method – метод, за аналогією з Class для класів. Оскільки об'єкт типу Class дає можливість отримати інформацію про клас, об'єкт типу Field – отримати інформацію про «поле класу», а Method – про «метод класу». І ось що з ними можна робити:

Код на Java Опис
Class[] interfaces = List.class.getInterfaces();
Отримуємо список «об'єктів класу» для інтерфейсів класу List
Class parent = String.class.getSuperclass();
Отримуємо «об'єкт класу» батьківського класу для класу String
Method[] methods = List.class.getMethods();
Отримуємо список методів, які є в класу List
String s = String.class.newInstance();
Створюємо новий об'єкт класу String
String s = String.class.newInstance();
Method m = String.class.getMethod("length");
int length = (int) m.invoke(s);
Отримуємо метод length у класу String, викликаємо його в рядка s

— Вау! Оце реально круто!

— Радий, що тобі сподобалося.