title: 【学习之路】反射学习
draft: true
tags:


Java Reflection概述

当加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个类的对象看到类的结构。这个对象就像一面镜子透过这个镜子看到类的结构,所以,我们形象的称之为反射

Class类

在Object类中定义了以下的方法,此方法将被所有子类继承

  • public fianl Class getClass()

以上方法返回值的类型必须一个Class类,此类是Java反射的源头。

  • Class本身也是一个类
  • Class对象只能由系统建立对象
  • 一个加载的类在JVM中只有一个Class实列
  • 一个Class对象对应的是一个加载到JVM中的一个.Class文件
  • 每个类的实列都会记得自己是由哪个Class实列所生成
  • 通过Class可以完整的得到一个类中所有被加载的结构
  • Class类是Reflection的根源,针对任何你想动态加载运行的类,唯有先获得相应的Class对象

Class类中的常用方法

方法名 功能说明
static Class forName(String name) 返回指定类名 name 的 Class 对象
Object newInstance() 调用缺省构造函数,返回该Class对象的一个实例
getName() 返回此Class对象所表示的实体(类、接口、数组类、基本类型 或void)名称
Class getSuperClass() 返回当前Class对象的父类的Class对象
Class [] getInterfaces() 获取当前Class对象的接口
ClassLoader getClassLoader() 返回该类的类加载器
Class getSuperclass() 返回表示此Class所表示的实体的超类的Class
Constructor[] getConstructors() 返回一个包含某些Constructor对象的数组
Field[] getDeclaredFields() 返回Field对象的一个数组
Method getMethod(String name,Class … paramTypes) 返回一个Method对象,此对象的形参类型为paramType

ClassLoader

  1. // 1.获取一个系统类加载器
  2. ClassLoader classloader = ClassLoader.getSystemClassLoader();
  3. System.out.println(classloader);
  4. // 2.获取系统类加载器的父类加载器,即扩展类加载器
  5. classloader = classloader.getParent();
  6. System.out.println(classloader);
  7. // 3.获取扩展类加载器的父类加载器,即引导类加载器
  8. classloader = classloader.getParent();
  9. System.out.println(classloader);
  10. // 4.测试当前类由哪个类加载器进行加载
  11. classloader = Class.forName("exer2.ClassloaderDemo").getClassLoader();
  12. System.out.println(classloader);
  13. // 5.测试JDK提供的Object类由哪个类加载器加载
  14. classloader = Class.forName("java.lang.Object").getClassLoader();
  15. System.out.println(classloader);
  16. // 6.关于类加载器的一个主要方法:getResourceAsStream(String str):获取类路径下的指定文件的输入流
  17. InputStream in = null;
  18. in = this.getClass().getClassLoader().getResourceAsStream("exer2\\test.properties");
  19. System.out.println(in);

获取运行时类的完整结构


获取属性结构

  1. Class<Person> clazz = Person.class;
  2. // 获取属性结构
  3. // getFields():获取当前运行时类其弗雷中声明为public访问权限的属性
  4. Field[] fields = clazz.getFields();
  5. for (Field field : fields) {
  6. System.out.println(field);
  7. }
  8. System.out.println("-----");
  9. // getDeclaredFields():获取当前运行时类中所有的属性,不包含父类中的属性
  10. Field[] declaredFields = clazz.getDeclaredFields();
  11. for (Field declaredField : declaredFields) {
  12. System.out.println(declaredField);
  13. }
  1. Class<Person> clazz = Person.class;
  2. Field[] declaredFields = clazz.getDeclaredFields();
  3. for (Field declaredField : declaredFields) {
  4. // 获取权限修饰符
  5. int modifiers = declaredField.getModifiers();
  6. System.out.println(Modifier.toString(modifiers));
  7. // 获取数据类型
  8. Class<?> type = declaredField.getType();
  9. System.out.println(type);
  10. // 获取变量名
  11. String name = declaredField.getName();
  12. System.out.println(name);
  13. }

获取方法结构

  1. Class<Person> clazz = Person.class;
  2. // 获取当前运行时类及其所有父类中声明为public权限的方法
  3. Method[] methods = clazz.getMethods();
  4. for (Method method : methods) {
  5. System.out.println(method);
  6. System.out.println("--");
  7. }
  8. // 获取当当前运行时类中的所有方法,不包括父类中的方法
  9. Method[] declaredMethods = clazz.getDeclaredMethods();
  10. for (Method declaredMethod : declaredMethods) {
  11. System.out.println(declaredMethod);
  12. System.out.println("--");
  13. }
  1. Class<Person> clazz = Person.class;
  2. Method[] declaredMethods = clazz.getDeclaredMethods();
  3. for (Method declaredMethod : declaredMethods) {
  4. // 获取方法声明的注解
  5. Annotation[] annotations = declaredMethod.getAnnotations();
  6. for (Annotation annotation : annotations) {
  7. System.out.print(annotation);
  8. }
  9. // 获取权限修饰符
  10. System.out.print(Modifier.toString(declaredMethod.getModifiers()));
  11. // 获取返回值类型
  12. System.out.print(declaredMethod.getReturnType().getName());
  13. // 获取方法名
  14. System.out.print(declaredMethod.getName());
  15. // 获取形参列表,参数类型
  16. Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
  17. if (!(parameterTypes == null && parameterTypes.length == 0)){
  18. for (int i = 0; i < parameterTypes.length; i++) {
  19. if (i == parameterTypes.length - 1){
  20. System.out.print(parameterTypes[i].getName() + "args_" + i);
  21. break;
  22. }
  23. System.out.print(parameterTypes[i].getName() + "args_" + i + ",");
  24. }
  25. }
  26. // 抛出的异常
  27. Class<?>[] exceptionTypes = declaredMethod.getExceptionTypes();
  28. if (exceptionTypes.length > 0){
  29. System.out.print("throws");
  30. for (int i = 0; i < exceptionTypes.length; i++) {
  31. if (i == exceptionTypes.length -1){
  32. System.out.println(exceptionTypes[i].getName());
  33. }
  34. System.out.println(exceptionTypes[i].getName() + ",");
  35. }
  36. }
  37. System.out.println();
  38. }