В дополнение к предоставлению нам различной информации о получении занятий в период компиляции, Java также позволяет нам получать различную информацию о классах в течение периода прогона посредством отражения. Получить информацию класса через размышление и получение информации о классе, вы можете получить следующий связанный контент:
Эта статья также представит Java Reflection из вышеуказанных аспектов. Все коды, связанные с этой статьей, отражены
Во -первых, класс Java выпускается в качестве объекта исследования для размышлений. Содержание класса следующее:
открытый абстрактный класс отца, реализует Runnable {public void dosomething () {System.out.println ("Do Things ..."); }} public Class exampleBject Extends ChostObject {public int age = 30; public String name = "byhieg"; Частный целый ряд баллов = 60; public void printName () {System.out.println (name); } 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 integer getScore () {return Score; } public void setScore (Integer Score) {this.Score = оценка; } public exampleObject () {} public exampleObject (string name) {} public exampleObject (int age, integer score) {} @Override public void dosomething () {super.dosomething (); } @Override public void run () {System.out.println ("run ..."); }}Класс объект
Наше приложение будет использовать точку знаний о рефлексии. Мы должны хотеть получить информацию класса во время выполнения и выполнить некоторые конкретные операции на основе информации класса. Затем первое, что нужно получить информацию о классе, и в JDK представлен объект класса для сохранения информации класса. Следовательно, первый шаг в отражении - получить объект класса. Есть два способа получить классовые объекты в JDK.
Первый в том, что если вы знаете имя класса при написании кода, вы можете напрямую получить объект класса следующим образом:
Class exampleObjectClass = ExampleObject.class;
Второй тип заключается в том, что если вы не знаете имя класса при написании кода, но во время выполнения вы можете получить строку имени класса, и вы можете получить объект класса следующим образом:
Class exampleObjectClass = Class.forName("cn.byhieg.reflectiontutorial.ExampleObject");
Обратите внимание, что этот метод должен иметь 2 условия. Во -первых, строка в ForName должна быть полностью квалифицированным именем, а во -вторых, класс класса должен быть ниже пути пути к классу, потому что метод будет выдвинуть исключение ClassNotFoundException.
После получения этого объекта класса вы можете получить различную информацию о классе. Некоторая информация была упомянута в начале. Ниже давайте поговорим о информации о классе, которая не была упомянута.
Получите имя класса
Есть два способа получить имя класса, один - getName (), а другой - GetSiMplename (). Первый получает полностью квалифицированное имя, а второе получает имя этого класса без имени пакета. Посмотрите на следующий пример: объект класса, который был получен через приведенный выше код.
String fullClassName = exampleObjectClass.getName (); String sompleclassname = exampleobjectclass.getSimplename (); System.out.println (FullClassName); System.out.println (SimpleClassName); System.out.println (SimpleClassName);
Результаты следующие:
cn.byhieg.reflectiontutorial.exampleBjectExampleObject
Получите имя пакета класса, родительский класс и интерфейс реализации
Имя пакета и родительский класс класса могут быть получены через следующий код.
// Получить информацию о пакете пакета apackage = exampleobjectClass.getPackage (); System.out.println (apackage); // Получить класс родительского класса SuperClass = exampleObjectClass.getSuperClass (); System.out.println (superclass.getSimplename ());
Результаты следующие:
Пакет cn.byhieg.reflectiontutorialfatherobject
Очевидно, что получение возврата значения родительского класса также является объектом класса. Затем вы можете использовать этот объект, чтобы получить некоторую информацию о родительском классе, например, оценить, является ли родительский класс абстрактным классом.
System.out.println("父类是不是抽象类" + Modifier.isAbstract(superClass.getModifiers()));
GetModifiers могут получить модификаторы класса, тем самым получить модификаторы класса. Конечно, эти GetModifiers можно назвать не только объектами класса, но и объекты метода могут быть вызваны.
Вы можете использовать метод в классе java.lang.reflect.modifier, чтобы проверить тип модификатора:
Modifier.isabstract (int modifiers); modifier.isfinal (int modifiers); modifier.isinterface (int modifiers); modifier.isnative (int modifiers); modifier.isprivate (int modifiers); модификатор. модификаторы); modifier.issstrict (int modifiers); modifier.issynchronized (int modifiers); modifier.istransient (int modifiers); modifier.isvolatile (int modifiers);
Кроме того, мы также можем получить интерфейс, реализованный родительским классом
// Получить класс интерфейса [] classe = superclass.getInterfaces (); System.out.println ("Интерфейсы родительского класса" + классы [0]);Поскольку классы Java могут реализовать множество интерфейсов, они используют массивы, но когда они фактически используют их, вам нужно сначала определить длину массива.
Ниже мы сосредоточимся на объяснении приведенного выше контента.
Конструктор
Используя Java Reflection, вы можете получить конструктор класса и динамически создать объект во время выполнения на основе конструктора. Во -первых, Java получает экземпляр конструктора с помощью:
// ConstructorConstructor [] Constructors = exampleObjectClass.getConstructors (); for (Constructor Constructor: Constructors) {System.out.println (constructor.toString ()); }Результаты следующие:
Public cn.byhieg.reflectiontutorial.exampleObject (int, java.lang.integer) public cn.byhieg.reflectiontutorial.exampleObject (java.lang.string) Public cn.byhieg.reflectionTututorial.exampleObject ()
Если вы знаете тип параметра конструктора для доступа заранее, вы можете использовать следующий метод для получения указанного конструктора следующим образом:
Конструктор конструктор = exampleobjectclass.getConstructor (String.class); System.out.println (constructor.toString ());
Результат очевидно:
public cn.byhieg.reflectiontutorial.ExampleObject(java.lang.String)
Другой конструктор также может быть получен следующим образом
Конструктор конструктор = exampleobjectclass.getConstructor (int.class, integer.class); System.out.println (constructor.toString ());
Кроме того, если мы не знаем параметры конструктора и можем получить только все объекты конструктора, мы можем получить параметры, которые каждый конструктор использует следующим образом:
Constructor [] Constructors = exampleObjectClass.getConstructors (); for (Constructor Constructor: Constructors) {class [] parameterTypes = constructor.getParameterTypes (); System.out.println ("Параметры конструктора как Следует ===================================================================== =========================================================================== for (class clz: parametertypes) {System.out.println ("parametertype" + clz.tostring ());Результаты следующие:
Параметры конструктора следующие ============================================================================================================
Здесь видно, что метод конструкции без параметра не печатает результат. Объект класса основного типа и объект класса типа ссылки разные.
Теперь объект может быть создан динамически на основе различной информации из конструктора.
Object Object = Constructor.NewInstance (1100); System.out.println (object.toString ());
Есть два условия для создания объекта. Первый создается через конструктор параметров. Во -вторых, объект конструктора должен быть получен через GetConstructor, который передает информацию о параметрах.
Первое условие заключается в том, что для объектов, которые могут быть созданы без методов построения параметров, нет необходимости получать объект конструктора. Объект класса вызывает метод NewInstance () и создает объект напрямую.
Второе условие состоит в том, что объект конструктора должен быть получен через форму example objectclass.getConstructor (String.class); Было бы неправильно получить массив конструкторов через GetConstructors, а затем вызовать указанный объект конструктора для создания объекта в JDK1.8. Но JDK1.6 нормальный.
переменная
Используя Java Reflection, вы можете получить переменную информацию о классе во время выполнения, и вы можете создать объект и установить его значение переменной в соответствии с вышеуказанным методом. Во -первых, все публичные переменные получаются посредством следующего метода:
Field [] fields = exampleObjectClass.getFields (); для (поле поле: Fields) {System.out.println ("переменная:" + field.tostring ()); }Результаты следующие:
Переменная: public int cn.byhieg.reflectiontutorial.exampleobject.age Переменная: public java.lang.string cn.byhieg.reflectiontutorial.exampleObject.name
Очевидно, что все полученные общественные переменные являются общедоступными, а вышеупомянутая частная переменная оценка не получена.
Так же, как конструктор, мы можем указать имя параметра, а затем получить указанную переменную:
Field Field = exampleObjectClass.getfield ("AGE"); System.out.println ("переменная:" + field.tostring ());Имя, полученное методом ToString приведенной выше переменной, слишком длинное. Java предоставляет метод getName для полевого класса, который возвращает имя переменной, записанной в классе. Приведенный выше код может быть изменен на Field.getName ().
Отражение не только обеспечивает способ получить переменные, но и обеспечивает способ установить значения переменных. Следуя следующему методу, вы можете изменить значение переменной динамически сгенерированного класса:
ExampleObject object = ((examentObject) constructor1.newinstance ("byhieg")); System.out.println («Первоначальный возраст - + object.age); Field.Set (Object, 10); System.out.println («Возраст после изменения - + object.age);Результаты следующие:
Первоначальный возраст составляет 30, а возраст после изменения - 10
Согласно вышеуказанному коду, вы можете получить объект полевого объекта с именем AGE, затем вызвать метод установки объекта, пройти объект и значение, которое будет изменено, а затем вы можете изменить значение объекта. Обратите внимание, что этот метод полезен не только для переменных членов, но и для статических переменных. Конечно, если это статическая переменная, это нормально, чтобы пройти NULL без прохождения объекта.
метод
В дополнение к предоставлению нам переменной информации класса, Java Reflection также предоставляет нам информацию о методе. Отражение позволяет нам получить имя метода, параметры метода, тип возврата метода и методы вызова.
Во -первых, получите метод через следующий код:
// Общедоступный метод метода выходного класса [] methods = exampleObjectClass.getMethods (); для (метод метода: методы) {System.out.println ("method ="+ method.getName ()); }Код, который выглядит знакомо как получение переменных. GetName вызывается непосредственно здесь, чтобы получить имя метода, написанное в классе. Записав это, вы должны, естественно, думать, что Java также предоставляет конкретные методы, основанные на параметрах.
Method Method = exampleObjectClass.getMethod ("setge", int.class); System.out.println (method.getName ());Разница здесь состоит в том, что метод GetMethod также должен пройти в информацию о типе параметра, отражение предоставляет метод для получения параметров метода и типа возврата. Примеры получения параметров метода следующие:
Method Method = exampleObjectClass.getMethod ("setge", int.class); System.out.println (method.getName ()); for (class clz: method.getParameterTypes ()) {System.out.println ("Параметр метода" + clz.getName ()); }Результаты следующие:
Параметр int метода настройки
Пример получения типа возврата метода заключается в следующем:
System.out.println(method.getReturnType().getName());
Результаты следующие:
void
Кроме того, Java Reflection поддерживает методы, полученные с помощью вызовов. Примеры следующие:
method.invoke(exampleObjectClass.newInstance(),1);
Первый параметр envoke является этим объектом, и второй параметр представляет собой массив с переменной длиной, и параметры метода передаются. Как объекты полевых вещей, для статических методов вы можете передавать нулевые и вызововать статические методы.
Частные переменные и частные методы
Приведенный выше метод может получить только публичные методы и переменные, но не может получить непубличные модифицированные методы и переменные. Java предоставляет дополнительные методы для получения непубличных переменных и методов. То есть частные переменные и методы получают через GetDeclaredFields и методы GetDeclaredMethods. Он также поддерживает использование getDeclaredfield (имя переменной) и getDeclaredMethod (имя метода) для получения указанного имени переменной и имени метода. Однако объекты полевых объектов и объекты методов, полученные таким образом, не могут быть непосредственно использованы. Эти объекты должны называться SetAccessible (true) для нормального использования. Следующий метод может быть таким же, как указано выше.
аннотация
Сначала напишите класс, содержащий аннотации:
@Myannotation (name = "byhieg", value = "hello world") открытый класс AnnotationObject {@myannotation (name = "field", value = "variable") поля открытого строки; @Myannotation (name = "method", value = "method") public void dosomething () {System.out.println ("Do Do"); } public void dootherthing (@myannotation (name = "param", value = "param") string param) {}}@hareveration (armentpolicy.runtime) public @Interface myannotation {public String name (); public String value ();}Java предоставляет нам информацию о получении классовых аннотаций во время выполнения, и мы можем получить классные аннотации, методы аннотации, аннотации параметров и аннотации переменных.
Как и вышеупомянутый метод сбора, Java предоставляет два метода сбора. Одним из них является получение всех аннотаций и вернуть массив, а второе - указать указанные аннотации.
Давайте возьмем классовую аннотацию в качестве примера, чтобы объяснить следующие два способа получения.
Класс clz = annotationobject.class; Аннотация [] аннотации = clz.getannotations (); Аннотация аннотации = Clz.getAnnotation (AnnotationObject.class);
Затем последующая обработка может быть выполнена на основе полученной аннотации. Ниже приведен пример обработки:
Для (аннотационная аннотация: аннотации) {if (аннотационный экземпляр myannotation) {myannotation myannotation = (myannotation) аннотация; System.out.println ("name:" + myannotation.name ()); System.out.println ("value:" + myannotation.value ()); }}Приведенные выше классовые аннотации получаются путем вызова getannotations с использованием объекта класса. Метод аннотации и переменные аннотации одинаковы. Я называю getDeclaredAnnations, используя объекты методов и объекты полевых объектов соответственно для получения аннотаций. Мне нечего сказать. См. Например, код отражения
Аннотации параметров являются относительно неприятным предметом. Метод сбора сравнивается. Первый шаг - сначала получить объект метода и вызов GetParameterannations. Однако это возвратное значение представляет собой двумерный массив, потому что объект метода имеет много параметров, и каждый параметр может иметь много аннотаций. Примеры следующие:
Method Method1 = clz.getMethod ("dootherthing", string.class); Аннотация [] [] annotationInparam = method1.getParameterannotations (); Class [] params = method1.getParameterTypes (); int i = 0; для (аннотация [] аннотации: AnnotationInParam) {класс para = params [i ++]; Для (аннотационная аннотация: аннотации) {if (аннотационный экземпляр myannotation) {myannotation myannotation = (myannotation) аннотация; System.out.println ("param:" + para.getName ()); System.out.println ("name:" + myannotation.name ()); System.out.println ("value:" + myannotation.value ()); }}}Дженерики
Поскольку дженерики Java реализованы путем стирания, трудно напрямую получить информацию о конкретном параметризованном типе генерики, но мы можем получить общую информацию через косвенную форму, используя отражение. Например, следующий класс:
открытый класс geneicObject {public list <string> списки; public List <string> getLists () {return Lists; } public void setlists (list <string> lists) {this.lists = lists; }}Если метод возвращает общий класс, мы можем вызвать getGenericReturnType через объект Method, чтобы получить GetGenericRETURNTYPE, чтобы получить конкретный тип параметризации этого общего класса. Посмотрите на следующий код:
Класс clz = geneicObject.class; Method Method = clz.getMethod ("getLists"); Type generictype = method.getGenericReturnType (); if (generictype экземпляр ParameterizedType) {parameterizedType parameterizedType = (((parameterizedType) genericType); Type [] types = parameterizedtype.getactualtypearguments (); для (тип типа: типы) {class actualClz = ((class) type); System.out.println ("Тип параметризации:" + actualClz); }}Результаты следующие:
参数化类型为: class java.lang.String
Шаги немного громоздки, поэтому следующее объяснение:
Я получил конкретную информацию о дженеках, просмотрев результаты.
Если ни один метод возвращает общий тип, то мы также можем получить параметризованный тип общего типа по параметру метода в качестве общего класса, такого как метод Setlists в вышеуказанном классе. Примеры следующие:
Метод setMethod = clz.getMethod ("setlists", list.class); Type [] genericParameterTypes = setMethod.getGenericParameterTypes (); для (тип genericParameterType: GenericParameterTypes) {System.out.println ("GenericParameterTypes IS:" + genericParameterType.getTypEname ()); if (genericParameterType экземпляр ParameterizedType) {parameterizedType parameterizedType = (((параметризованный тип) genericParameterType); System.out.println ("ParameterizedType IS:" + parameterizedType.getTypEname ()); Типы типов [] = параметризованный type.getactualtypearguments (); для (тип типа: типы) {system.out.println ("Параметризованный тип:" + ((class) type) .getName ()); }}}Результаты выполнения следующие:
GenericParameterTypes - это: java.util.list <java.lang.string> Параметризованный тип
Поскольку параметры метода могут иметь более одного универсального типа, мы получаем GetGenericParameterTypes, чтобы получить массив, и нам нужно определить, имеет ли каждый элемент параметризованный тип. Последующие шаги похожи на вышеупомянутые, поэтому я не буду много говорить.
Если даже параметры метода не содержат общих классов, то остается только последний случай, через тип переменной, то есть используется класс поля. Примеры следующие:
Field Field = clz.getfield ("списки"); Тип типа = field.getGenericType (); if (экземпляр типа параметризованного типа) {parameterizedType parameterizedType = (((параметризованный type) тип); Type [] types = parameterizedtype.getactualtypearguments (); для (type type1: types) {System.out.println ("Параметризованный тип:" + ((class) type1) .gettypename ()); }}Принцип такой же, как и выше, за исключением того, что объект типа находится через Field.getGenericType (), поэтому я не буду много говорить о оставшихся операциях.
Это введение в получение параметризованного типа дженериков посредством отражения.
Множество
Отражение Java может работать на массиве, включая создание массива, доступ к значениям в массиве и получение класса объекта массива.
Давайте поговорим об этом просто, создав массив и доступ к значениям в массиве: использование класса массива в отражении - это тот, который ниже пакета Refert.
// Создать массив типа int с длиной 3 int [] intarray = (int []) array.newinstance (int.class, 3); // присвоить значение массиву через отражение для (int i = 0; i <intarray.length; i ++) {array.set (intarray, i, i+2); } // массив в форме отражения, получите значение в массиве для (int i = 0; i <intarray.length; i ++) {System.out.println (array.get (intarray, i)); }Выше приведено создать массив и получить доступ к значениям в массиве, используя отражение.
Для объектов класса, которые получают массив, вы можете просто использовать int []. Class или использовать class.forname, который является странным способом написать:
Класс clz = class.forname ("[i"); System.out.println (clz.getTypEname ());Результат:
int[]
Строка в этом имени, [ представляет массив, я представляю int, float Is F , Double IS и т. Д. Если вы хотите получить массив обычных объектов, используйте следующую форму:
Class stringClz = Class.forName("[Ljava.lang.String;");
[ Скажем, это массив, правая сторона L - это имя класса, а правая сторона типа - это ; ;
Этот способ получить класс объекта массива слишком громоздкий.
После получения класса объекта массива можно назвать некоторые из его уникальных методов, таких как призвание GetComponentType , чтобы получить информацию о типов членов массива. Например, массив Int - это тип члена, который является Int.
System.out.println(clz.getComponentType().getTypeName());
Результат int
Суммировать
На этот раз различные применения размышлений заканчиваются этим, и в будущем могут быть подробные объяснения знаний. Для конкретного кода вы можете посмотреть на код отражения
В пакете SRC есть различные классы, а в тестовом классе это доступ к этим классам.
Выше всего содержание этой статьи. Я надеюсь, что содержание этой статьи поможет всем, кто учится или работа. Я также надеюсь поддержать Wulin.com больше!