反射机制允许程序在执行期,借助 反射API 取得任何类的内部信息,并能直接操作任何对象的内部属性及方法。
.class 文件被加载到 JVM 后,在堆内存的方法区中产生了一个 Class 类型的对象,这个对象包含了该类的结构信息。


Java 反射机制提供的功能:

  • 获取有关类的一切信息(所在的包、实现的接口、标注的注解、构造器、属性、方法 等)
  • 调用有关类的一切方法(构造器、成员方法 等)

    Class 类

    获取 Class 的对象的方式

    1. public void TestReflect() throws ClassNotFoundException {
    2. // 方式1
    3. Class<Person> clazz1 = Person.class;
    4. // 方式2
    5. Person person = new Person();
    6. Class clazz2 = person.getClass();
    7. // 方式3
    8. Class clazz3 = Class.forName("类的路径");
    9. // 方式4
    10. // 获取到 ClassLoader(这里获取到的是:AppClassLoader)
    11. ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    12. Class clazz4 = classLoader.loadClass("类的路径");
    13. }

  1. @Test
  2. public void TestReflect() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
  3. ClassLoader classLoader = ClassLoader.getSystemClassLoader();
  4. Class clazz1 = classLoader.loadClass("com.hfy.community.entity.po.Person");
  5. ClassLoader classLoader1 = clazz1.getClassLoader();
  6. // 源代码中给出的基础类的简单名称。
  7. // Person
  8. String simpleName = clazz1.getSimpleName();
  9. // getConstructor 只返回公共构造函数
  10. // getDeclaredConstructor 返回所有的构造函数(不包含父类中声明的构造器)
  11. Constructor<?>[] constructors = clazz1.getConstructors();
  12. Constructor<?>[] declaredConstructors = clazz1.getDeclaredConstructors();
  13. String methodName = "setName";
  14. // 类的指定方法
  15. Method method = clazz1.getDeclaredMethod(methodName, String.class);
  16. String fieldName = "name";
  17. // 类的指定属性
  18. Field field = clazz1.getDeclaredField(fieldName);
  19. LoginRequired annotation = (LoginRequired) clazz1.getAnnotation(LoginRequired.class);
  20. // 类对象表示的实体(类,接口,数组类,原始类型或空白)的名称
  21. // 即全限定类名
  22. // class com.hfy.community.entity.po.Person
  23. String name = clazz1.getName();
  24. // 为此类型的名称返回一个内容丰富的字符串。
  25. // 底层调用了 getName()
  26. // com.hfy.community.entity.po.Person
  27. String typeName = clazz1.getTypeName();
  28. Annotation[] annotations = clazz1.getAnnotations();
  29. // 类实现的接口
  30. Class[] interfaces = clazz1.getInterfaces();
  31. // 该类的父类
  32. Class superclass = clazz1.getSuperclass();
  33. // 该类的父类,带泛型
  34. Type genericSuperclass = clazz1.getGenericSuperclass();
  35. // 类所在的包信息
  36. Package aPackage = clazz1.getPackage();
  37. // com.hfy.community.entity.po
  38. String packageName = aPackage.getName();
  39. }

Constructor 类

  1. @Test
  2. public void TestReflect() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
  3. ClassLoader classLoader = ClassLoader.getSystemClassLoader();
  4. Class clazz1 = classLoader.loadClass("com.hfy.community.entity.po.Person");
  5. Constructor constructor = clazz1.getConstructor(null);
  6. // 构造器上标注的注解
  7. Annotation[] annotations = constructor.getAnnotations();
  8. // 返回此对象所表示的可执行文件的 Java 语言修饰符。
  9. int modifiers = constructor.getModifiers();
  10. // 构造器所属的类
  11. // class com.hfy.community.entity.po.Person
  12. Class aClass = constructor.getDeclaringClass();
  13. // 构造器的方法名
  14. // com.hfy.community.entity.po.Person
  15. String name = constructor.getName();
  16. // 返回一个 类对象的数组,类表示由该对象表示的底层可执行文件声明的异常类型。
  17. Class[] exceptionTypes = constructor.getExceptionTypes();
  18. // 返回一个 Parameter 对象的数组,表示由该对象表示的底层可执行文件的所有参数。
  19. Parameter[] parameters = constructor.getParameters();
  20. // 构造器的参数上标注的注解
  21. Annotation[][] parameterAnnotations = constructor.getParameterAnnotations();
  22. }

Method 类

  1. @Test
  2. public void TestReflect() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
  3. ClassLoader classLoader = ClassLoader.getSystemClassLoader();
  4. Class clazz = classLoader.loadClass("com.hfy.community.entity.po.Person");
  5. Person person = (Person) clazz.newInstance();
  6. // 当前运行时类及其父类中声明为 public 访问权限的方法
  7. Method[] methods = clazz.getMethods();
  8. // 当前运行时类中声明的所有方法(不包含父类中声明的方法,也包括 private 访问权限的方法)
  9. Method[] declaredMethods = clazz.getDeclaredMethods();
  10. // 方法的调用
  11. Object result = methods[0].invoke(person, null);
  12. // 方法上标注的所有注解
  13. Annotation[] annotations = declaredMethods[0].getAnnotations();
  14. // 方法的返回值的类型
  15. Class<?> returnType = declaredMethods[0].getReturnType();
  16. // 方法名
  17. String name = declaredMethods[0].getName();
  18. // 形参列表
  19. Class[] parameterTypes = declaredMethods[0].getParameterTypes();
  20. // 声明 throws 的所有异常类型
  21. Class[] exceptionTypes = declaredMethods[0].getExceptionTypes();
  22. }

Annotation 类

Parameter 类

Field 类

  1. @Test
  2. public void TestReflect() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
  3. ClassLoader classLoader = ClassLoader.getSystemClassLoader();
  4. Class clazz = classLoader.loadClass("com.hfy.community.entity.po.Person");
  5. Person person = (Person) clazz.newInstance();
  6. // 类的属性
  7. Field[] fields = clazz.getFields();
  8. // 设置指定对象的属性值
  9. fields[0].set(person, "value");
  10. // 获取指定对象的属性值
  11. fields[0].get(person);
  12. // 属性上标注的所有注解
  13. Annotation[] annotations = fields[0].getAnnotations();
  14. // 属性的类型
  15. Class<?> type = fields[0].getType();
  16. // 属性的名字
  17. String name = fields[0].getName();
  18. // 属性的修饰符
  19. int modifiers = fields[0].getModifiers();
  20. }