1. Reflection(反射)是被视为动态语言的关键 反射机运行在程序执行期借助于Reflection API取得任何类的内部信息 并能直接操作任意对象的内部属性及方法
    2. 加载完类后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象) 这个对象包含了完整的类的结构信息 我们可以通过这个对象看到类的结构
      1. 这个对象就像一面镜子 透过镜子看到类的结构 所以 我们形象的称之为:反射
    3. 什么时候应用反射?
      1. 在不确定要执行类的类型(对象)时 如浏览器向服务器发送请求 服务器根据浏览器请求 通过反射创建对应的对象. 进行处理
    4. 反射和封装性冲突吗?
      1. 不冲突
    5. 类加载过程
      1. 程序经过javac.exe命令后 会生成一个或多个字节码文件(.class文件) 接着我们用java.exe命令对某个字节码文件进行解释运行. 相当于将某个字节码文件加载到内存中. 此过程称为类加载
      2. 加载到内存中的类 称为运行时类
      3. Class类的实例就是一个运行时类
    6. 反射的常用方法 ```java

    /**

    • @author:LYY 创建时间:2022/5/12 */ public class ReflectionTest {

      /**

      • 实例化Class的常用方法
      • 注 四个class实例在内存中都是同一个 */ @Test void testOne() {

        // 方式一 通过类.class Class clazz1 = Person.class;

        // 方式二 通过对象的getClass方法 Person person = new Person(); Class clazz2 = person.getClass();

        try {

        1. // 方式三 通过Class静态方法
        2. Class<?> clazz3 = Class.forName("com.atguigu.Person");
        3. // 方式四 通过类加载器
        4. ClassLoader classLoader = Person.class.getClassLoader();
        5. Class<?> clazz4 = classLoader.loadClass("com.atguigu.Person");
        6. // 获取当前类上的注解
        7. Annotation[] annotations = clazz4.getAnnotations();
        8. for (Annotation annotation : annotations) {
        9. System.out.println(annotation);
        10. }

        } catch (ClassNotFoundException e) {

        1. e.printStackTrace();

        }

        }

        /**

      • 通过Class实例 创造运行时类实例 */ @Test void testInstance() { Class personClass = Person.class; Person person = null; try {

        1. // 通过无参构造器创建运行时类对象
        2. person = personClass.newInstance();
        3. // 通过指定参数构造器 创建运行时类对象
        4. Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class, Integer.class);
        5. // 放开权限 保证私有的构造器也可以被调用
        6. declaredConstructor.setAccessible(true);
        7. Person person1 = declaredConstructor.newInstance("你好", 22);
        8. System.out.println(person);
        9. System.out.println(person1);
        10. // 获取运行时类的所有构造器

        } catch (InstantiationException e) {

        1. e.printStackTrace();

        } catch (IllegalAccessException e) {

        1. e.printStackTrace();

        } catch (NoSuchMethodException e) {

        1. e.printStackTrace();

        } catch (InvocationTargetException e) {

        1. e.printStackTrace();

        } System.out.println(“person = “ + person); }

        /**

      • 获取运行时类的所有属性
      • 使用(赋值 输出)运行时类的属性 */ @Test void testField() { Class personClass = Person.class; // 获取当前运行时类的所有public权限的属性,包含父类中定义的属性 Field[] fields = personClass.getFields(); // 获取当前运行时类的所有权限属性 不包含父类中的属性 Field[] declaredFields = personClass.getDeclaredFields(); for (Field f: declaredFields

        1. ) {
        2. // 获取当前运行时类属性的权限修饰符
        3. int modifiers = f.getModifiers();
        4. System.out.print(Modifier.toString(modifiers)+"\t");
        5. // 获取当前运行时类的数据类型
        6. Class<?> type = f.getType();
        7. System.out.print(type.getName() + "\t");
        8. // 获取当前运行时类的属性的名称
        9. System.out.println(f.getName());

        }

        try {

        1. // 获取运行时类的指定属性 只能获取权限为public的属性
        2. //Field name = personClass.getField("name");
        3. // 没有public权限的name 结果为null
        4. //System.out.println("name = " + name);
        5. Field age = personClass.getDeclaredField("age");
        6. // 开放权限 使私有属性可以被赋值
        7. age.setAccessible(true);
        8. // 给指定对象属性 赋值指定值
        9. Person person = personClass.newInstance();
        10. age.set(person, 45);
        11. person.setName("草泥马");
        12. System.out.println(person);
        13. System.out.println();

        } catch (NoSuchFieldException e) {

        1. e.printStackTrace();

        } catch (InstantiationException e) {

        1. e.printStackTrace();

        } catch (IllegalAccessException e) {

        1. e.printStackTrace();

        } }

        /**

      • 获取当前运行时类的方法 */ @Test void testMethods() { Class clazz = Person.class; // 返回当前运行时类的所有公共方法 包含父类方法 Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) {

        1. System.out.println(methods[i]);

        } System.out.println(“*“); // 获取当前运行时类的所有方法 不包含父类 Method[] declaredMethods = clazz.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) {

        1. // 获取当前前运行时类方法的权限修饰符
        2. int modifiers = declaredMethod.getModifiers();
        3. System.out.print(Modifier.toString(modifiers)+"\t");
        4. // 获取当前运行时类方法的返回值类型
        5. Type genericReturnType = declaredMethod.getGenericReturnType();
        6. System.out.print(genericReturnType.getTypeName() + "\t");
        7. // 获取当前运行时类的方法名称
        8. String name = declaredMethod.getName();
        9. System.out.print(name+"\t");
        10. // 获取当前方法形参
        11. Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
        12. if (parameterTypes.length != 0) {
        13. System.out.print("(");
        14. for (Class<?> parameterType : parameterTypes) {
        15. System.out.print(parameterType+"\t");
        16. }
        17. System.out.print(")");
        18. }
        19. /* Type[] genericParameterTypes = declaredMethod.getGenericParameterTypes();
        20. System.out.println("-------------------");
        21. if (genericParameterTypes.length != 0) {
        22. for (Type genericParameterType : genericParameterTypes) {
        23. System.out.println("+" + genericParameterType);
        24. }
        25. }*/
        26. // 获取当前运行时类方法的返回值
        27. Class<?> returnType = declaredMethod.getReturnType();
        28. if (returnType != null) {
        29. System.out.print(returnType.getName());
        30. }
        31. System.out.println();

        }

        try {

        1. // 获取指定运行时类的方法
        2. Method show = clazz.getDeclaredMethod("show");
        3. show.setAccessible(true);
        4. // 运行指定运行时类对象的show方法 无参方法
        5. show.invoke(clazz.newInstance());
        6. Method show1 = clazz.getDeclaredMethod("show", String.class);
        7. // 释放权限 运行调用私有方法
        8. show1.setAccessible(true);
        9. show1.invoke(null, "CNM");

        } catch (NoSuchMethodException e) {

        1. e.printStackTrace();

        } catch (InvocationTargetException e) {

        1. e.printStackTrace();

        } catch (IllegalAccessException e) {

        1. e.printStackTrace();

        } catch (InstantiationException e) {

        1. e.printStackTrace();

        } }

        /**

      • 获取运行时类的构造器
      • 获取运行时类的父类
      • 获取运行时类父类的泛型
      • 获取运行时类的接口
      • 获取运行时类所在的java包 */ @Test void testConstructors() { Class personClass = Person.class; // 获取运行时类中所有公开的构造器 Constructor<?>[] constructors = personClass.getConstructors(); for (Constructor<?> constructor : constructors) {

        1. System.out.println(constructor);

        } System.out.println(); // 获取当前运行时类中所有的构造器 Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors(); for (Constructor<?> declaredConstructor : declaredConstructors) {

        1. System.out.println(declaredConstructor);

        }

        System.out.println(); // 获取运行时类的父类 Type genericSuperclass = personClass.getGenericSuperclass(); System.out.println(genericSuperclass); // 获取运行时类的泛型 ParameterizedType parameterizedType = (ParameterizedType)genericSuperclass; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); System.out.println(actualTypeArguments[0]); System.out.println(); // 获取运行时类的接口 Class<?>[] interfaces = personClass.getInterfaces(); System.out.println(interfaces[0]); // 可以显示接口中的泛型信息 前提时接口存在泛型 Type[] genericInterfaces = personClass.getGenericInterfaces(); System.out.println(genericInterfaces[0]); System.out.println(); // 获取运行时类所在的java包 Package aPackage = personClass.getPackage(); System.out.println(aPackage); } }

    /**

    • @author LYY 自定义注解 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.FIELD}) @interface MyAnnotation {

      String value() default “哈哈哈”; }

    /**

    • @author:LYY 创建时间:2022/5/12 */ @MyAnnotation class Person extends User implements PersonTest{
    1. private String name;
    2. private Integer age;
    3. public String getName() {
    4. return name;
    5. }
    6. public void setName(String name) {
    7. this.name = name;
    8. }
    9. public Integer getAge() {
    10. return age;
    11. }
    12. public void setAge(Integer age) {
    13. this.age = age;
    14. }
    15. @Override
    16. public String toString() {
    17. return "Person{" +
    18. "name='" + name + '\'' +
    19. ", age=" + age +
    20. '}';
    21. }
    22. public Person() {
    23. }
    24. private Person(String name) {
    25. }
    26. public Person(String name, Integer age) {
    27. this.name = name;
    28. this.age = age;
    29. }
    30. public void show() {
    31. System.out.println("测试一");
    32. }
    33. public int show(int a) {
    34. return 1;
    35. }
    36. private static void show(String name) {
    37. System.out.println("我时Person类中的私有方法!" + "形参是:" + name);
    38. }
    39. @Override
    40. public void test01() {
    41. System.out.println("接口中方法!");
    42. }

    }

    /**

    • @author LYY 接口 */ interface PersonTest {

      /**

      • 无意义的方法 */ void test01(); }

    /**

    • @author:LYY 创建时间:2022/5/12 person类父类 */ class User implements Comparable{

      private String userName; private int userAge;

      public User() { }

      public User(String userName, int userAge) {

      1. this.userName = userName;
      2. this.userAge = userAge;

      }

      public String getUserName() {

      1. return userName;

      }

      public void setUserName(String userName) {

      1. this.userName = userName;

      }

      public int getUserAge() {

      1. return userAge;

      }

      public void setUserAge(int userAge) {

      1. this.userAge = userAge;

      }

      private String eat(String eat) {

      1. System.out.println("user类的eat方法!");
      2. return eat;

      }

      public void hi() {

      1. System.out.println("我是中国人!");

      }

      @Override public int compareTo(Object o) {

      1. return 0;

      } }

    ```