Java Reflection е процес на изследване или модифициране на поведението на даден клас по време на изпълнение .
The java.lang.Class клас предоставя много методи, които могат да се използват за получаване на метаданни, изследване и промяна на поведението на даден клас по време на изпълнение.
Пакетите java.lang и java.lang.reflect предоставят класове за отражение на java.
Къде се използва
API Reflection се използва главно в:
- IDE (интегрирана среда за разработка) напр. Eclipse, MyEclipse, NetBeans и др.
- Дебъгер
- Инструменти за тестване и др.
- По колко начина можем да получим екземпляра на класа Class?
- Как да създадете инструмента javap?
- Как да създадете инструмента appletviewer?
- Как да получите достъп до частния метод извън класа?
java.lang.Class клас
Класът java.lang.Class изпълнява основно две задачи:
- предоставя методи за получаване на метаданните на клас по време на изпълнение.
- предоставя методи за изследване и промяна на поведението на даден клас по време на изпълнение.
Често използвани методи на клас клас:
Метод | Описание |
---|---|
1) публичен низ getName() | връща името на класа |
2) публичен статичен клас forName(String className) хвърля ClassNotFoundException | зарежда класа и връща препратката към клас клас. |
3) public Object newInstance() хвърля InstantiationException, IllegalAccessException | създава нов екземпляр. |
4) публичен булев isInterface() | проверява дали е интерфейс. |
5) публичен булев isArray(); | проверява дали е масив. |
6) публичен булев isPrimitive() | проверява дали е примитивен. |
7) публичен клас getSuperclass() | връща препратката към клас суперклас. |
8) public Field[] getDeclaredFields() хвърля SecurityException | връща общия брой полета от този клас. |
9) публичен метод [] getDeclaredMethods() хвърля SecurityException | връща общия брой методи от този клас. |
10) public Constructor[] getDeclaredConstructors() хвърля SecurityException | връща общия брой конструктори от този клас. |
11) публичен метод getDeclaredMethod(Име на низ,Class[] parameterTypes) хвърля NoSuchMethodException,SecurityException | връща екземпляра на клас метод. |
Как да получа обекта на класа Class?
Има 3 начина да получите екземпляра на класа Class. Те са както следва:
- forName() метод на клас Class
- метод getClass() на клас Object
- синтаксисът .class
1) forName() метод на клас Class
- се използва за динамично зареждане на класа.
- връща екземпляра на клас клас.
- Трябва да се използва, ако знаете пълното име на класа. Това не може да се използва за примитивни типове.
Нека видим простия пример за метод forName().
средно срещу средно
Име на файл: Test.java
class Simple{} public class Test{ public static void main(String args[]) throws Exception { Class c=Class.forName('Simple'); System.out.println(c.getName()); } }
Изход:
Simple
2) метод getClass() на клас Object
Той връща екземпляра на клас клас. Трябва да се използва, ако знаете вида. Освен това може да се използва с примитиви.
Име на файл: Test.java
class Simple{} class Test{ void printName(Object obj){ Class c=obj.getClass(); System.out.println(c.getName()); } public static void main(String args[]){ Simple s=new Simple(); Test t=new Test(); t.printName(s); } }
Изход:
Simple
3) Синтаксисът .class
Ако даден тип е наличен, но няма екземпляр, тогава е възможно да се получи клас чрез добавяне на '.class' към името на типа. Може да се използва и за примитивни типове данни.
Име на файл: Test.java
class Test{ public static void main(String args[]){ Class c = boolean.class; System.out.println(c.getName()); Class c2 = Test.class; System.out.println(c2.getName()); } }
Изход:
boolean Test
Определяне на обекта на класа
Следните методи на клас клас се използват за определяне на обекта на класа:
1) публичен булев isInterface(): определя дали посоченият обект Class представлява тип интерфейс.
2) публичен булев isArray(): определя дали този обект Class представлява клас масив.
3) публичен булев isPrimitive(): определя дали посоченият обект Class представлява примитивен тип.
Нека видим простия пример за API за отражение, за да определим типа обект.
Име на файл: Test.java
class Simple{} interface My{} class Test{ public static void main(String args[]){ try{ Class c=Class.forName('Simple'); System.out.println(c.isInterface()); Class c2=Class.forName('My'); System.out.println(c2.isInterface()); }catch(Exception e){System.out.println(e);} } }
Изход:
false true
Плюсове и минуси на отражението
Отражението на Java винаги трябва да се използва с повишено внимание. Въпреки че отражението предоставя много предимства, то има и някои недостатъци. Нека първо обсъдим предимствата.
Професионалисти: Проверката на интерфейси, класове, методи и полета по време на изпълнение е възможна с помощта на отражение, дори без да се използват техните имена по време на компилиране. Възможно е също така да се извикват методи, да се инстанцира ясно или да се зададе стойност на полета с помощта на отражение. Помага при създаването на визуални среди за разработка и браузъри на класове, които предоставят помощ на разработчиците да напишат правилния код.
java стекове
Минуси: Използвайки отражение, човек може да наруши принципите на капсулирането. Възможно е достъп до частните методи и полета на клас чрез отражение. По този начин отражението може да изтече важни данни към външния свят, което е опасно. Например, ако някой получи достъп до частните членове на клас и му зададе нулева стойност, тогава другият потребител от същия клас може да получи NullReferenceException и това поведение не се очаква.
Друг недостатък е режийното представяне. Тъй като типовете в отражението се разрешават динамично, JVM (Java Virtual Machine) оптимизация не може да се извърши. Следователно операциите, извършвани от отражения, обикновено са бавни.
Заключение
Поради гореспоменатите недостатъци обикновено е препоръчително да избягвате използването на отражение. Това е разширена функция, която трябва да се използва само от програмисти или разработчици, които имат добри познания по основи на езика. Винаги помни! Всеки път, когато се използва отражение, сигурността на приложението е компрометирана.
Следващ урок за API за теми на размисъл
метод newInstance().Разбиране на инструмента javap
създаване на javap инструмент
създаване на инструмент за преглед на аплети
Извикване на частен метод от друг клас