English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Объяснение reflection в java

Содержание

  1. Java reflection API
  2. Создание экземпляра объекта через反射
  3. Вызов частного метода с помощью отражения
  4. О инструменте javap
  5. Справочные материалы

Java reflection API

Java reflectionэто процесс получения свойств и методов класса или изменения поведения класса в состоянии выполнения.

Класс java.lang.Classпредоставляет множество методов для получения метаданных, проверки и изменения поведения класса в runtime.

Java reflection в основном涉及到 java.lang и java.lang.reflect пакеты.

примеры приложений с использованием反射

  1. IDE, такие как Eclipse, MyEclipse, NetBeans и т.д.;
  2. дилеры;
  3. инструменты для тестирования и т.д.;
  4. Основные фреймворки, такие как Spring, Hibernate и т.д.;

Класс java.lang.Class

Класс java.lang.Class предоставляет следующие две основные функции:

  1. Предоставляет методы для доступа к метаданным класса во время выполнения;
  2. Предоставляет методы для проверки и изменения поведения класса во время выполнения;

Обычные методы класса java.lang.Class

Метод Описание
1) public String getName() Возвращает имя класса
2) public static Class forName(String className) throws ClassNotFoundException Загружает класс и возвращает объект Class
3) public Object newInstance() throws InstantiationException,IllegalAccessException Создает объект экземпляра
4) public boolean isInterface() Определяет, является ли это интерфейсом
5) public boolean isArray() Определяет, является ли это массивом
6) public boolean isPrimitive() Определяет, является ли это базовым типом данных
7) public Class getSuperclass() Возвращает ссылку на класс родителя Class
8) public Field[] getDeclaredFields() throws SecurityException Возвращает массив полей членов класса
9) public Method[] getDeclaredMethods() throws SecurityException Возвращает массив методов класса
10) public Constructor[] getDeclaredConstructors() throws SecurityException Возвращает массив методов класса
11) public Method getDeclaredMethod(String name,Class[] parameterTypes) throws NoSuchMethodException,SecurityException Возвращает метод с указанным типом параметра в классе

Как получить объект Class

Есть три способа, вот они:

  1. Метод forName() класса Class, динамическая загрузка, во время выполнения, начальная загрузка класса и выполнение статического инициализации класса
  2. Метод getClass() объекта, статическая загрузка (загружена во время компиляции)
  3. Синтаксис .class, статическая загрузка (загружена при компиляции)}

Пример метода forName():

Может быть использован для динамической загрузки, когда вы знаете полное имя класса. Обратите внимание, что примитивные типы данных не подлежат этому методу;

package tmp;
class Simple
{
}
public class Test
{
 public static void main(String args[]) throws ClassNotFoundException
 {
 Class<?> c = Class.forName("tmp.Simple");
 System.out.println(c.getName());
 System.out.println(c.getSimpleName());
 }
}
tmp.Simple
Simple

Пример метода getClass():

Получение объекта Class из экземпляра объекта

package tmp;
class Simple
{
}
public class Test
{
 void printName(Object obj)
 {
 }
 public static void main(String args[])
 {
 Simple s = new Simple();
 Class<? extends Object> c = s.getClass();
 System.out.println(c.getName());
 System.out.println(c.getSimpleName());
 }
}
tmp.Simple
Simple

Пример синтаксиса .class

Действует на имя класса, также может применяться к примитивным типам данных, например:

package tmp;
public class Test
{
 public static void main(String args[])
 {
 Class<Boolean> c = boolean.class;
 System.out.println(c.getName());
 Class<Test> c2 = Test.class;
 System.out.println(c2.getName());
 }
}
boolean
tmp.Test

Определение типа объекта Class

Следующие методы могут быть использованы для определения типа объекта Class:

1) public boolean isInterface(): Соответствует ли интерфейсу
2) public boolean isArray(): Соответствует ли массиву
3) public boolean isPrimitive(): Соответствует ли оригинальному типу данных

Пример кода:

package tmp;
class Simple
{
}
interface My
{
}
public class Test
{
 public static void main(String args[])
 {
 try
 {
 Class<?> c = Class.forName("tmp.Simple");
 System.out.println(c.isInterface());
 Class<?> c2 = Class.forName("tmp.My");
 System.out.println(c2.isInterface());
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}
false
true

Создание экземпляра объекта через反射

Есть два способа, вот они:

  1. Создается через метод newInstance() объекта Class, этот способ может вызывать только безпараметрический конструктор;
  2. Создается через метод newInstance() объекта Constructor, этот способ подходит для параметризованного конструктора и может разрушить режим Singleton, вызов частного конструктора;

Таким образом, обычно第二种 способ больше подходит для использования, чем первый.

Пример вызова метода newInstance() объекта Class

package tmp;
class Simple
{
 void message()
 {
 System.out.println("Hello Java");
 }
}
public class Test
{
 public static void main(String args[])
 {
 try
 {
 Class<?> c = Class.forName("tmp.Simple");
 Simple s = (Simple) c.newInstance();
 s.message();
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}

Hello Java

Пример вызова метода newInstance() объекта Constructor

Обратите внимание, что можно получить указанный конструктор по типу传入ных параметров, а также изменить ограничения доступа к конструктору.

package tmp;
import java.lang.reflect.Constructor;
class Simple
{
 private String msg;
 void message()
 {
 System.out.println("Hello Java," + msg);
 }
 private Simple(String s){
 this.msg = s;
 }
}
public class Test
{
 public static void main(String args[])
 {
 try
 {
 Class<?> c = Class.forName("tmp.Simple");
 Constructor<?> con = c.getDeclaredConstructor(String.class);
 con.setAccessible(true);
 Simple s = (Simple) con.newInstance("...");
 s.message();
 }
 catch (Exception e)
 {
 System.out.println(e);
 }
 }
}

Hello Java,...

Вызов частного метода с помощью отражения

С помощью отражения мы можем вызывать частные методы других классов, что включает java.lang.Class и java.lang.reflect.Method классы;

Здесь主要用于Method类的setAccessible() и invoke() методы, первая изменяет права доступа, вторая вызывает метод.

Пример вызова метода с параметрами в частной методе:

package tmp;
import java.lang.reflect.Method;
class A
{
 private void cube(int n)
 {
 System.out.println(n * n * n);
 }
}
class Test
{
 public static void main(String args[]) throws Exception
 {
 Class<A> c = A.class;
 Object obj = c.newInstance();
 Method m = c.getDeclaredMethod("cube", new Class[]{ int.class });
 m.setAccessible(true);
 m.invoke(obj, 4);
 }
}

О инструменте javap

Использование команды javap можно反асsembler java байткод файла, показать класс файла полей свойств, конструкторов, обычных методов информации;

Инструкции по использованию:

Пример javap java.lang.Object:

Пример javap -c Test:

Напишите простую класс Test, как показано ниже:

package tmp;
class Simple
{
}
public class Test
{
 public static void main(String args[])
 {
 System.out.println("Hello");
 }
}

Ввести javap -c Test:

Справочные материалы

Основная часть перевода, некоторые изменения были внесены

http://www.javatpoint.com/java-reflection

Вот и все, что есть в этой статье, я надеюсь, что содержимое статьи поможет вам в изучении или работе, и я также надеюсь, что вы будете активно поддерживать руководство по крику!

Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему автору, содержимое предоставлено пользователями Интернета, сайт не имеет права собственности, не был отредактирован вручную, и не несет ответственности за соответствующие юридические вопросы. Если вы обнаружите содержимое,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (во время отправки письма, пожалуйста, замените # на @) для сообщения о нарушении и предоставьте соответствующие доказательства. Если будет установлено, что содержимое является нарушением авторских прав, сайт немедленно удаляет涉嫌侵权的内容。

Смотри также