java reflection tutorial with examples
Цей відео-посібник пояснює, що таке Reflection та як це реалізувати за допомогою API Reflection:
Відображення в Java - це перевірка та зміна поведінки програми під час виконання.
За допомогою цього API відображення ви можете перевіряти класи, конструктори, модифікатори, поля, методи та інтерфейси під час виконання. Наприклад, ви можете отримати назву класу або ви можете отримати деталі про приватних членів класу.
Прочитайте всю нашу Навчальна серія JAVA для більш глибокого розуміння концепцій Java.
Ось відео-посібник з роздумів про Java:
Що ви дізнаєтесь:
Відображення в Java
Ми усвідомлюємо, що в даному класі ми можемо змінювати його властивості та методи під час компіляції, і це дуже легко зробити. Незалежно від того, властивості та методи є анонімними чи мають імена, їх можна змінити за нашим бажанням під час компіляції.
Але ми не можемо змінювати ці класи чи методи чи поля під час виконання на льоту. Іншими словами, дуже важко змінити поведінку різних компонентів програмування під час виконання, особливо для невідомих об'єктів.
Мова програмування Java надає функцію, яка називається “Відображення” що дозволяє нам модифікувати поведінку класу, поля чи методу під час виконання.
Таким чином, відображення можна визначити як a “Техніка перевірки та модифікації поведінки невідомого об’єкта під час виконання. Об’єктом може бути клас, поле або метод ”.
Відображення - це «Інтерфейс програмування програм» (API), що надається Java.
Процес 'Роздуми' зображений нижче.

У наведеному вище поданні ми бачимо, що ми маємо невідомий об’єкт. Потім ми використовуємо API Reflection для цього об’єкта. Як результат, ми можемо змінити поведінку цього об’єкта під час виконання.
Таким чином, ми можемо використовувати Reflection API у наших програмах з метою модифікації поведінки об’єкта. Об'єктами можуть бути будь-які подібні до методів, інтерфейсів, класів тощо. Ми перевіряємо ці об'єкти, а потім змінюємо їх поведінку під час виконання за допомогою API відображення.
У Java «java.lang» та «java.lang.reflect» - це два пакети, що забезпечують класи для роздумів. Спеціальний клас “java.lang.Class” надає методи та властивості для вилучення метаданих, за допомогою яких ми можемо перевірити та змінити поведінку класу.
Ми використовуємо Reflection API, наданий вищевказаними пакетами, для модифікації класу та його членів, включаючи поля, методи, конструктори тощо під час виконання. Відмінною особливістю Reflection API є те, що ми також можемо маніпулювати приватними даними або методами класу.
API Reflection в основному використовується в:
- Відображення в основному використовується в інструментах налагодження, JUnit та фреймворках для перевірки та зміни поведінки під час виконання.
- IDE (інтегроване середовище розробки) Наприклад Eclipse IDE, NetBeans тощо.
- Тестові інструменти тощо
- Він використовується, коли у вашому додатку є сторонні бібліотеки та коли ви хочете знати про доступні класи та методи.
API відображення в Java
Використовуючи Reflection API, ми можемо реалізувати роздуми про такі сутності:
- Польовий : Клас Field містить інформацію, яку ми використовуємо для оголошення змінної або поля, як тип даних (int, double, String тощо), модифікатор доступу (приватний, загальнодоступний, захищений тощо), ім'я (ідентифікатор) та значення.
- Метод : Клас Метод може допомогти нам витягти таку інформацію, як модифікатор доступу методу, тип повернення методу, ім'я методу, типи параметрів методу та типи винятків, викликані методом.
- Будівельник : Клас конструктора надає інформацію про конструктор класу, що включає модифікатор доступу до конструктора, ім'я конструктора та типи параметрів.
- Редагувати : Клас модифікатора дає нам інформацію про конкретний модифікатор доступу.
Усі вищезазначені класи є частиною пакету java.lang.reflect. Далі ми обговоримо кожен із цих класів та використаємо приклади програмування, щоб продемонструвати роздуми про ці класи.
Почнемо спочатку з класу java.lang.Class.
java.lang.Class Class
Клас java.lang. Клас зберігає всю інформацію та дані про класи та об'єкти під час виконання. Це основний клас, який використовується для роздумів.
Клас java.lang.Class забезпечує:
- Методи отримання метаданих класу під час виконання.
- Методи перевірки та модифікації поведінки класу під час виконання.
Створіть java.lang.Class Objects
Ми можемо створити об'єкти java.lang.Class, використовуючи один із наступних параметрів.
java, додаючи елементи до масиву
# 1) .класне розширення
Перший варіант створення об’єкта Класу - використання розширення .class.
Наприклад,якщо Test - це клас, то ми можемо створити об’єкт Class наступним чином:
Class obj_test = Test.class; Тоді ми можемо використовувати obj_test для відображення, оскільки цей об’єкт матиме всю інформацію про клас Test.
# 2) метод forName ()
Метод forName () приймає ім'я класу як аргумент і повертає об'єкт Class.
Наприклад,об'єкт класу Test можна створити наступним чином:
class obj_test = Class.forName (“Test”); # 3) метод getClas ()
Метод getClass () використовує об'єкт класу для отримання об'єкта java.lang.Class.
Наприклад,розглянемо наступний фрагмент коду:
Test obj = new Test (); Class obj_test = obj.getClass (); У першому рядку ми створили об’єкт класу Test. Потім, використовуючи цей об'єкт, ми викликали метод 'getClass ()', щоб отримати об'єкт obj_test з java.lang.Class.
Отримайте модифікатори Super Class & Access
java.lang.class надає метод “getSuperClass ()”, який використовується для отримання суперкласу будь-якого класу.
Подібним чином він забезпечує метод getModifier (), який повертає модифікатор доступу класу.
Наведений нижче приклад демонструє метод getSuperClass ().
import java.lang.Class; import java.lang.reflect.*; //define Person interface interface Person { public void display(); } //declare class Student that implements Person class Student implements Person { //define interface method display public void display() { System.out.println('I am a Student'); } } class Main { public static void main(String() args) { try { // create an object of Student class Student s1 = new Student(); // get Class object using getClass() Class obj = s1.getClass(); // get the superclass of Student Class superClass = obj.getSuperclass(); System.out.println('Superclass of Student Class: ' + superClass.getName()); } catch(Exception e) { e.printStackTrace(); } } }Вихідні дані

У наведеному вище прикладі програмування інтерфейс Person визначається за допомогою одиночного методу ‘display ()’. Потім ми визначаємо клас Student, який реалізує інтерфейс person. В основному методі ми використовуємо метод getClass () для отримання об'єкта Class, а потім отримуємо доступ до батьківського або суперкласу об'єкта Student за допомогою методу getSuperClass ().
Отримати інтерфейси
Якщо клас реалізує деякі інтерфейси, тоді ми можемо отримати ці імена інтерфейсів, використовуючи метод getInterfaces () методу java.lang.Class. Для цього ми повинні виконати роздуми про клас Java.
У наведеному нижче прикладі програмування показано використання методу getInterfaces () у Java Reflection.
import java.lang.Class; import java.lang.reflect.*; //define Interface Animals and PetAnimals interface Animals { public void display(); } interface PetAnimals { public void makeSound(); } //define a class Dog that implements above interfaces class Dog implements Animals, PetAnimals { //define interface method display public void display() { System.out.println('This is a PetAnimal::Dog'); } //define interface method makeSound public void makeSound() { System.out.println('Dog makes sound::Bark bark'); } } class Main { public static void main(String() args) { try { // create an object of Dog class Dog dog = new Dog(); // get class object Class obj = dog.getClass(); // get the interfaces implemented by Dog Class() objInterface = obj.getInterfaces(); System.out.println('Class Dog implements following interfaces:'); //print all the interfaces implemented by class Dog for(Class citem : objInterface) { System.out.println('Interface Name: ' + citem.getName()); } } catch(Exception e) { e.printStackTrace(); } } }Вихідні дані

У наведеній вище програмі ми визначили два інтерфейси, тобто Animals та PetAnimals. Потім ми визначаємо клас Dog, який реалізує обидва ці інтерфейси.
У основному методі ми отримуємо об’єкт класу Dog у java.lang.Class для виконання відображення. Потім ми використовуємо метод getInterfaces () для отримання інтерфейсів, реалізованих класом Dog.
Відображення: Отримати значення поля
Як уже зазначалося, пакет java.lang.reflect забезпечує клас Field, який допомагає нам відображати поле або дані членів класу.
Нижче перераховані методи, передбачені класом Field для відображення поля.
| Метод | Опис |
|---|---|
| getField ('fieldName') | Повертає поле (загальнодоступне) із зазначеною назвою поля. |
| getFields () | Повертає всі загальнодоступні поля (як для класу, так і для суперкласу). |
| getDeclaredFields () | Отримує всі поля класу. |
| getModifier () | Повертає цілочисельне представлення модифікатора доступу поля. |
| набір (classObject, значення) | Присвоює зазначене значення полю. |
| отримати (classObject) | Отримує значення поля. |
| setAccessible (логічне значення) | Зробіть приватне поле доступним, передавши true. |
| getDeclaredField ('fieldName') | Повертає поле із зазначеним ім'ям. |
Нижче наведено два приклади рефлексії, які демонструють рефлексію на державному та приватному полі.
Наведена нижче програма Java демонструє роздуми про публічне поле.
import java.lang.Class; import java.lang.reflect.*; class Student { public String StudentName; } class Main { public static void main(String() args) { try{ Student student = new Student(); // get an object of the class Class Class obj = student.getClass(); // provide field name and get the field info Field student_field = obj.getField('StudentName'); System.out.println('Details of StudentName class field:'); // set the value of field student_field.set(student, 'Lacey'); // get the access modifier of StudentName int mod1 = student_field.getModifiers(); String modifier1 = Modifier.toString(mod1); System.out.println('StudentName Modifier::' + modifier1); // get the value of field by converting in String String typeValue = (String)student_field.get(student); System.out.println('StudentName Value::' + typeValue); } catch(Exception e) { e.printStackTrace(); } } }Вихідні дані

У цій програмі ми оголосили клас 'Студент', який має загальнодоступне поле StudentName. Потім, використовуючи інтерфейс API класу Field, ми виконуємо відображення поля StudentName і отримуємо його модифікатор доступу та значення.
Наступна програма виконує роздуми над приватним полем класу. Операції подібні, за винятком того, що для приватного поля зроблено ще один додатковий виклик функції. Ми повинні викликати setAccessible (true) для приватного поля. Потім ми проводимо роздуми над цим полем подібним чином, як публічне поле.
import java.lang.Class; import java.lang.reflect.*; class Student { private String rollNo; } class Main { public static void main(String() args) { try { Student student = new Student(); // get the object for class Student in a Class. Class obj = student.getClass(); // access the private field Field field2 = obj.getDeclaredField('rollNo'); // make the private field accessible field2.setAccessible(true); // set the value of rollNo field2.set(student, '27'); System.out.println('Field Information of rollNo:'); // get the access modifier of rollNo int mod2 = field2.getModifiers(); String modifier2 = Modifier.toString(mod2); System.out.println('rollNo modifier::' + modifier2); // get the value of rollNo converting in String String rollNoValue = (String)field2.get(student); System.out.println('rollNo Value::' + rollNoValue); } catch(Exception e) { e.printStackTrace(); } } }Вихідні дані

Рефлексія: Метод
Подібно до полів класу, ми також можемо роздумувати про методи класу та змінювати їх поведінку під час виконання. Для цього ми використовуємо клас Method пакета java.lang.reflect.
Нижче перераховані функції, надані класом Method для відображення методу класу.
| Метод | Опис |
|---|---|
| getMethods () | Отримує всі загальнодоступні методи, визначені в класі та його суперкласі. |
| getDeclaredMethod () | Повертає методи, оголошені в класі. |
| getName () | Повертає імена методів. |
| getModifiers () | Повертає цілочисельне представлення модифікатора доступу методу. |
| getReturnType () | Повертає тип повернення методу. |
У наведеному нижче прикладі показано відображення методів класу в Java із використанням вищевказаних API.
import java.lang.Class; import java.lang.reflect.*; //declare a class Vehicle with four methods class Vehicle { public void display() { System.out.println('I am a Vehicle!!'); } protected void start() { System.out.println('Vehicle Started!!!'); } protected void stop() { System.out.println('Vehicle Stopped!!!'); } private void serviceVehicle() { System.out.println('Vehicle serviced!!'); } }class Main { public static void main(String() args) { try { Vehicle car = new Vehicle(); // create an object of Class Class obj = car.getClass(); // get all the methods using the getDeclaredMethod() in an array Method() methods = obj.getDeclaredMethods(); // for each method get method info for(Method m : methods) { System.out.println('Method Name: ' + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.print('Modifier: ' + Modifier.toString(modifier) + ' '); // get the return type of method System.out.print('Return Type: ' + m.getReturnType()); System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }Вихідні дані

У наведеній вище програмі ми бачимо, що метод getDeclaredMethods повертає масив методів, оголошених класом. Потім ми перебираємо цей масив і відображаємо інформацію про кожен метод.
Відображення: Конструктор
Ми можемо використовувати клас “Конструктор” пакета java.lang.reflect для перевірки та модифікації конструкторів класу Java.
Клас конструктора забезпечує для цього наступні методи.
| Метод | Опис |
|---|---|
| getConstructors () | Повертає всі конструктори, оголошені в класі, та його суперклас. |
| getDeclaredConstructor () | Повертає всі заявлені конструктори. |
| getName () | Отримує ім'я конструктора. |
| getModifiers () | Повертає цілочисельне представлення модифікатора доступу конструкторів. |
| getParameterCount () | Повертає загальну кількість параметрів для конструкторів. |
Наведений нижче приклад відображення демонструє відображення конструкторів класу в Java. Як і відображення методу, тут також метод getDeclaredConstructors повертає масив конструкторів для класу. Потім ми проходимо через цей масив конструктора, щоб відобразити інформацію про кожен конструктор.
import java.lang.Class; import java.lang.reflect.*; //declare a class Person with three constructors class Person { public Person() { } //constructor with no parameters public Person(String name) { } //constructor with 1 parameter private Person(String name, int age) {} //constructor with 2 parameters } class Main { public static void main(String() args) { try { Person person = new Person(); Class obj = person.getClass(); // get array of constructors in a class using getDeclaredConstructor() Constructor() constructors = obj.getDeclaredConstructors(); System.out.println('Constructors for Person Class:'); for(Constructor c : constructors) { // get names of constructors System.out.println('Constructor Name: ' + c.getName()); // get access modifier of constructors int modifier = c.getModifiers(); System.out.print ('Modifier: ' + Modifier.toString(modifier) + ' '); // get the number of parameters in constructors System.out.println('Parameters: ' + c.getParameterCount()); //if there are parameters, get parameter type of each parameter if(c.getParameterCount() > 0){ Class() paramList=c.getParameterTypes(); System.out.print ('Constructor parameter types :'); for (Class class1 : paramList) { System.out.print(class1.getName() +' '); } } System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }Вихідні дані

Недоліки відображення
Відображення є потужним, але його не слід застосовувати без розбору. Якщо можливо працювати без використання відбиття, то переважно уникати його використання.
Нижче перераховано кілька недоліків Reflection:
- Накладні витрати на продуктивність: Незважаючи на те, що відображення є потужною особливістю, світловідбиваючі операції все ж мають нижчі показники, ніж невідбивальні. Тому нам слід уникати використання відображень у критично важливих для продуктивності додатках.
- Обмеження безпеки: Оскільки відображення є функцією виконання, воно може вимагати дозволів на час роботи. Отже, для програм, які вимагають виконання коду в обмежених налаштуваннях безпеки, відбиття може не принести користі.
- Вплив внутрішніх органів: Використовуючи відображення, ми можемо отримати доступ до приватних полів та методів у класі. Таким чином, роздуми порушують абстракцію, яка може зробити код непортативним та дисфункціональним.
Часті запитання
Q # 1) Чому Reflection використовується в Java?
Відповідь: Використовуючи відображення, ми можемо перевіряти класи, інтерфейси, конструктори, поля та методи під час виконання, навіть якщо вони анонімні під час компіляції. Ця перевірка дозволяє нам змінити поведінку цих об'єктів під час виконання.
Q # 2) Де використовується Reflection?
Відповідь: Відображення використовується при написанні фреймворків, які взаємодіють із визначеними користувачем класами, при цьому програміст навіть не знає, якими будуть класи чи інші сутності.
Q # 3) Чи є Java Reflection повільним?
Відповідь: Так, це повільніше, ніж код, що не відображає.
Q # 4) Java Reflection погано?
Відповідь: Певним чином, так. Перш за все, ми втрачаємо безпеку під час компіляції. Без безпеки під час компіляції ми можемо отримати помилки під час роботи, які можуть вплинути на кінцевих користувачів. Також буде важко налагодити помилку.
Q # 5) Як зупинити відображення на Java?
Відповідь: Ми просто уникаємо використання рефлексії, пишучи операції без рефлексії. Або, можливо, ми можемо використовувати деякі загальні механізми, такі як спеціальна перевірка із відображенням.
Детальніше про Java Reflection
Пакет java.lang.reflect має класи та інтерфейси для відображення. А java.lang.class можна використовувати як точку входу для відображення.
Як отримати об’єкти класу:
1. Якщо у вас є екземпляр об’єкта,
клас c = obj.getclass ();
2. Якщо ви знаєте тип класу,
клас c = type.getClass ();
3. Якщо ви знаєте назву класу,
Клас c = Class.forName (“com.demo.Mydemoclass”);
Як отримати учасників класу:
Членами класу є поля (змінні класу) та методи.
- getFields () - Використовується для отримання всіх полів, крім приватних.
- getDeclaredField () - Використовується для отримання приватних полів.
- getDeclaredFields () - Використовується для отримання приватного та публічного полів.
- getMethods () - Використовується для отримання всіх методів, крім приватних.
- getDeclaredMethods () –Використовується для отримання державного та приватного методів.
Демо-програми:
ReflectionHelper.java:
Це клас, який ми збираємось перевірити за допомогою API відображення.
найкращий сайт для перегляду аніме безкоштовно
class ReflectionHelper { private int age; private String name; public String deptName; public int empID; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } } 
ReflectionDemo.java
public class ReflectionDemo { public static void main(String() args) throws NoSuchFieldException, SecurityException { //get the class Class ReflectionHelperclass=ReflectionHelper.class; //get the name of the class String className = ReflectionHelperclass.getName(); System.out.println('className=='+className); System.out.println('getModifiers'+ReflectionHelperclass.getModifier s()); System.out.println('getSuperclass'+ReflectionHelperclass.getSupercla ss()); System.out.println('getPackage'+ReflectionHelperclass.getPackage()); Field() fields =ReflectionHelperclass.getFields(); //getting only the public fields for(Field oneField : fields) { Field field = ReflectionHelperclass.getField(oneField.getName()); String fieldname = field.getName(); System.out.println('only the public fieldnames:::::'+fieldname); } //getting all the fields of the class Field() privatefields =ReflectionHelperclass.getDeclaredFields(); for(Field onefield : privatefields) { Field field = ReflectionHelperclass.getDeclaredField(onefield.getName()); String fieldname = field.getName(); System.out.println('all the fieldnames in the class:::'+fieldname); } Method() methods =ReflectionHelperclass.getDeclaredMethods(); for(Method m: methods) { System.out.println('methods::::'+m.getName()); } }}

Висновок
У цьому посібнику детально пояснено API відображення в Java. Ми побачили, як виконувати відображення класів, інтерфейсів, полів, методів та конструкторів, а також кілька недоліків відображення.
Рефлексія є відносно вдосконаленою функцією в Java, але її повинні використовувати програмісти, які мають тверду позицію в мові. Це тому, що це може спричинити несподівані помилки та результати, якщо не використовувати з обережністю.
Хоча відображення є потужним, ним слід користуватися обережно. Тим не менше, використовуючи рефлексію, ми можемо розробляти програми, які не знають про класи та інші сутності до часу виконання.
=> Подивіться тут посібник для початківців Java.
Рекомендована література
- Підручник з класу сканера Java із прикладами
- Java Integer та клас Java BigInteger з прикладами
- Підручник JAVA для початківців: 100+ практичних відео-підручників Java
- Вступ до мови програмування Java - Підручник з відео
- Що таке Java Java | Підручник з класу Java Vector з прикладами
- Інтерфейс Java та підручник з абстрактних класів із прикладами
- Метод підстроки Java () - Підручник із прикладами
- Підручник з Java Collections Framework (JCF)