反射(reflect)和注解

无反射无框架。

反射的介绍

  1. package com.powernode.p2;
  2. public class Demo01 {
  3. public static void main(String[] args) {
  4. // 正向创建 --- 静态的 --- 指腹为婚
  5. /*
  6. * 之所以叫做静态的, 是因为我们创建对象的时候类已经固定了
  7. * 也就是这句代码创建的就是Student的对象。不会是其他类的对象了
  8. */
  9. Student student = new Student("张三",20);
  10. System.out.println(student);
  11. System.out.println("-----------------------------------");
  12. // 使用反射 --- 动态的
  13. /*
  14. * 之所以叫做动态的是因为,我们创建对象的类没有固定,可以是任意的。
  15. *
  16. */
  17. try {
  18. Class<?> aClass = Class.forName(args[0]);
  19. Object obj = aClass.newInstance();
  20. System.out.println(obj);
  21. } catch (ClassNotFoundException e) {
  22. e.printStackTrace();
  23. } catch (IllegalAccessException e) {
  24. e.printStackTrace();
  25. } catch (InstantiationException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

1655188733294.png

Class类

  1. public final class Class<T> extends Object implements Serializable, GenericDeclaration, Type, AnnotatedElement
  • 类型参数:
    T - 由此 Class 对象建模的类的类型。例如,String.class 的类型是 Class。如果将被建模的类未知,则使用 Class

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

获取Class对象的四种方式

  1. package com.powernode.p2;
  2. /**
  3. * 获取Class对象
  4. *
  5. */
  6. public class Demo02 {
  7. public static void main(String[] args) {
  8. // FQCN(Fully Qualified Class Name) 全限定类名 包名.类名
  9. // 获取Class对象的方式一:Class.forName(String FQCN); --- 推荐使用,好处就是解耦
  10. try {
  11. Class<?> aClass = Class.forName("com.powernode.p2.Student");
  12. System.out.println(aClass);
  13. System.out.println(aClass.getName());
  14. } catch (ClassNotFoundException e) {
  15. e.printStackTrace();
  16. }
  17. System.out.println("--------------------------------");
  18. // 获取Class对象的方式二:数据类型.class --- 作为参数传递的时候比较常用
  19. Class<Student> studentClass = Student.class;
  20. System.out.println(studentClass);
  21. System.out.println(studentClass.getName());
  22. System.out.println(int.class);
  23. System.out.println(boolean.class);
  24. System.out.println(int[][].class);
  25. System.out.println(void.class);
  26. System.out.println("--------------------------------");
  27. // 获取Class对象的方式三:对象.getClass()
  28. Student student = new Student();
  29. Class<? extends Student> aClass = student.getClass();
  30. System.out.println(aClass);
  31. System.out.println(aClass.getName());
  32. System.out.println("--------------------------------");
  33. // 获取Class对象的方式四: 包装类.TYPE
  34. Class<Integer> integerClass = Integer.TYPE;
  35. System.out.println(integerClass);
  36. Class<Double> doubleClass = Double.TYPE;
  37. System.out.println(doubleClass);
  38. Class<Character> characterClass = Character.TYPE;
  39. System.out.println(characterClass);
  40. }
  41. }

使用反射获取包信息

  1. package com.powernode.p2;
  2. /**
  3. * 使用反射获取包的信息
  4. *
  5. * 反射机制就是将类的各个组成部分(属性,方法,构造器)封装为其它对象。
  6. *
  7. * 使用反射获取包的信息,会将封装成Package对象
  8. *
  9. */
  10. public class PackageDemo {
  11. public static void main(String[] args) {
  12. try {
  13. // 1. 获取Class
  14. Class<?> aClass = Class.forName("com.powernode.p2.Student");
  15. // 2. 拿到Class后,使用反射你就可以为所欲为
  16. Package aPackage = aClass.getPackage();
  17. System.out.println(aPackage);
  18. System.out.println(aPackage.getName());
  19. } catch (ClassNotFoundException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. }

使用反射获取类信息

  1. package com.powernode.p2;
  2. import java.lang.reflect.Modifier;
  3. /**
  4. * 使用反射获取类信息
  5. *
  6. */
  7. public class ClassDemo01 {
  8. public static void main(String[] args) {
  9. try {
  10. // Class.forName()得到的就是类的信息了
  11. Class<?> aClass = Class.forName("com.powernode.p2.Student");
  12. System.out.println(aClass.getName());
  13. // 获取类的修饰符信息
  14. int modifiers = aClass.getModifiers();
  15. System.out.println(modifiers); // 1 == public
  16. // 判断类是不是public修饰的
  17. System.out.println(Modifier.isPublic(modifiers));
  18. // 获取继承的父类
  19. Class<?> superclass = aClass.getSuperclass();
  20. System.out.println(superclass.getName());
  21. // 获取实现的接口
  22. // 父类实现的接口,子类是没有实现的
  23. Class<?>[] interfaces = aClass.getInterfaces();
  24. for (Class<?> anInterface : interfaces) {
  25. System.out.println(anInterface.getName());
  26. }
  27. } catch (ClassNotFoundException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. }

使用反射通过Class创建对象

  1. Class<?> aClass = Class.forName("com.powernode.p2.Student");
  2. System.out.println(aClass.getName());
  3. /*
  4. * 使用反射通过Class创建对象
  5. * aClass.newInstance()是通过无参构造创建对象
  6. * jdk9开始该方法被弃用了
  7. */
  8. Object obj = aClass.newInstance();
  9. System.out.println(obj);

使用反射获取字段

  1. package com.powernode.p2;
  2. import java.lang.reflect.Field;
  3. /**
  4. * 使用反射获取字段:
  5. * javabean中的成员变量也叫作字段Field
  6. *
  7. * 反射机制就是将类的各个组成部分(属性,方法,构造器)封装为其它对象。
  8. * 反射就会将成员变量信息封装成Field对象
  9. *
  10. *
  11. */
  12. public class FieldDemo01 {
  13. public static void main(String[] args) {
  14. Class<Student> studentClass = Student.class;
  15. try {
  16. // 获取指定的public字段
  17. // getField()可以获取本类定义的字段或者是继承的字段
  18. Field nameField = studentClass.getField("name");
  19. System.out.println(nameField);
  20. System.out.println(nameField.getName());
  21. System.out.println("-----------------------------");
  22. // 获取本类定义的或继承的所有public字段
  23. Field[] fields = studentClass.getFields();
  24. for (Field field : fields) {
  25. System.out.println("field= " + field);
  26. }
  27. System.out.println("-----------------------------");
  28. /*
  29. * Declared 已声明过的。
  30. * 1. 本类中定义的才叫做声明。
  31. * 2. Declared可以获取任意访问权限的
  32. *
  33. */
  34. Field ageField = studentClass.getDeclaredField("age");
  35. System.out.println(ageField);
  36. System.out.println(ageField.getName());
  37. // 获取字段的访问权限
  38. System.out.println(ageField.getModifiers());
  39. System.out.println("-----------------------------");
  40. Field[] declaredFields = studentClass.getDeclaredFields();
  41. for (Field declaredField : declaredFields) {
  42. System.out.println("declaredField= "+ declaredField);
  43. }
  44. } catch (NoSuchFieldException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. }

使用反射给字段赋值和取值

  1. package com.powernode.p2;
  2. import java.lang.reflect.Field;
  3. /**
  4. * 使用反射给字段赋值和取值
  5. */
  6. public class FieldDemo02 {
  7. public static void main(String[] args) {
  8. Class<Student> studentClass = Student.class;
  9. try {
  10. // 获取字段对象
  11. Field nameField = studentClass.getField("name");
  12. // 取值
  13. /*
  14. * get(Object obj)中的参数obi表示获取哪一个对象的字段
  15. */
  16. Student student = studentClass.newInstance();
  17. Object value = nameField.get(student);
  18. System.out.println(value); // null
  19. // 赋值
  20. /*
  21. * set(Object obj, Object value)
  22. * 第一个参数表示给哪个对象的字段赋值
  23. * 第二参数表示给字段赋什么值
  24. */
  25. nameField.set(student,"李四");
  26. value = nameField.get(student);
  27. System.out.println(value); // 李四
  28. System.out.println("------------------------------");
  29. // 给private int age字段取值和赋值
  30. Field ageField = studentClass.getDeclaredField("age");
  31. // 暴力访问
  32. // 私有的字段不论是取值还是赋值都需要设置暴力访问
  33. // 设置为true表示反射对象在使用时忽略Java语言访问检查
  34. // ageField.setAccessible(true);
  35. Object ageValue = ageField.get(student);
  36. System.out.println(ageValue); // 0
  37. ageField.set(student,23);
  38. ageValue = ageField.get(student);
  39. System.out.println(ageValue); // 23
  40. } catch (NoSuchFieldException e) {
  41. e.printStackTrace();
  42. } catch (IllegalAccessException e) {
  43. e.printStackTrace();
  44. } catch (InstantiationException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. }

使用反射获取构造信息

  1. package com.powernode.p2;
  2. import java.lang.reflect.Constructor;
  3. /**
  4. * 使用反射获取构造信息
  5. *
  6. * 反射机制就是将类的各个组成部分(属性,方法,构造器)封装为其它对象。
  7. *
  8. * 反射会将构造函数封装成Constructor对象
  9. *
  10. *
  11. */
  12. public class ConstructorDemo01 {
  13. public static void main(String[] args) {
  14. Class<Student> studentClass = Student.class;
  15. /*
  16. * getConstructor(Class<?>... parameterTypes)
  17. * 参数表示是的构造的参数类型的Class
  18. *
  19. */
  20. try {
  21. // 获取public的无参构造
  22. Constructor<Student> constructor = studentClass.getConstructor();
  23. System.out.println(constructor);
  24. System.out.println(constructor.getName());
  25. System.out.println("--------------------");
  26. // 获取public的带参构造
  27. Constructor<Student> constructor1 = studentClass.getConstructor(String.class,int.class);
  28. System.out.println(constructor1);
  29. System.out.println(constructor1.getName());
  30. System.out.println("--------------------");
  31. Constructor<?>[] constructors = studentClass.getConstructors();
  32. for (Constructor<?> constructor2 : constructors) {
  33. System.out.println("constructor2= " + constructor2);
  34. }
  35. System.out.println("--------------------");
  36. // 获取声明过的指定构造函数
  37. Constructor<Student> declaredConstructor = studentClass.getDeclaredConstructor(String.class);
  38. System.out.println(declaredConstructor);
  39. System.out.println("--------------------");
  40. // 获取声明过的所有构造函数
  41. Constructor<?>[] declaredConstructors = studentClass.getDeclaredConstructors();
  42. for (Constructor<?> declaredConstructor1 : declaredConstructors) {
  43. System.out.println("declaredConstructor1= " + declaredConstructor1);
  44. }
  45. } catch (NoSuchMethodException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. }

使用反射通过构造创建对象

  1. package com.powernode.p2;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.InvocationTargetException;
  4. /**
  5. * 使用反射通过构造创建对象
  6. *
  7. */
  8. public class ConstructorDemo02 {
  9. public static void main(String[] args) {
  10. Class<Student> studentClass = Student.class;
  11. try {
  12. Constructor<Student> constructor = studentClass.getConstructor();
  13. // 使用构造创建对象
  14. /*
  15. * newInstance(Object ... initargs)
  16. * 参数表示使用构造创建对象的时候传入的实际参数
  17. **/
  18. Student student = constructor.newInstance();
  19. System.out.println(student);
  20. System.out.println("-------------------------------");
  21. // public Student(String name, int age)
  22. Constructor<Student> constructor1 = studentClass.getConstructor(String.class, int.class);
  23. Student zhangsan = constructor1.newInstance("张三", 22);
  24. System.out.println(zhangsan);
  25. System.out.println("---------------------------");
  26. // private Student(String name)
  27. Constructor<Student> declaredConstructor = studentClass.getDeclaredConstructor(String.class);
  28. declaredConstructor.setAccessible(true);
  29. Student lisi = declaredConstructor.newInstance("李四");
  30. System.out.println(lisi);
  31. } catch (NoSuchMethodException e) {
  32. e.printStackTrace();
  33. } catch (IllegalAccessException e) {
  34. e.printStackTrace();
  35. } catch (InstantiationException e) {
  36. e.printStackTrace();
  37. } catch (InvocationTargetException e) {
  38. e.printStackTrace();
  39. }
  40. }
  41. }

使用反射获取方法信息

  1. package com.powernode.p2;
  2. import java.lang.reflect.Method;
  3. /**
  4. * 使用反射获取方法信息
  5. *
  6. * 反射机制就是将类的各个组成部分(属性,方法,构造器)封装为其它对象。
  7. *
  8. * 反射将方法的信息封装成Method对象
  9. *
  10. *
  11. */
  12. public class MethodDemo01 {
  13. public static void main(String[] args) {
  14. try {
  15. Class<?> aClass = Class.forName("com.powernode.p2.Student");
  16. /*
  17. * 获取指定的public方法,可以获取本类声明的,也可以获取继承父类的方法
  18. * getMethod(String name, Class<?>... parameterTypes)
  19. * 第一个参数表示方法的名字
  20. * 第二个参数表示方法形参类型的Class
  21. */
  22. Method setName = aClass.getMethod("setName", String.class);
  23. System.out.println(setName);
  24. System.out.println("--------------------");
  25. // 获取本类及父类的所有public方法
  26. Method[] methods = aClass.getMethods();
  27. for (Method method : methods) {
  28. System.out.println("method= " + method);
  29. }
  30. System.out.println("--------------------");
  31. Method study = aClass.getDeclaredMethod("study");
  32. System.out.println(study);
  33. } catch (ClassNotFoundException e) {
  34. e.printStackTrace();
  35. } catch (NoSuchMethodException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }

使用反射执行方法

  1. package com.powernode.p2;
  2. import java.lang.reflect.InvocationTargetException;
  3. import java.lang.reflect.Method;
  4. /**
  5. * 使用反射执行方法
  6. *
  7. */
  8. public class MethodDemo02 {
  9. public static void main(String[] args) {
  10. Class<Student> studentClass = Student.class;
  11. try {
  12. Method eatMethod = studentClass.getDeclaredMethod("eat", String.class);
  13. // 调用方法
  14. /*
  15. * Object invoke(Object obj, Object... args)
  16. * 第一参数表示执行哪一个对象的方法
  17. * 第二参数表示调用方法传入的实参
  18. *
  19. * 返回值表示调用方法后方法的返回值
  20. * void 返回就是null
  21. *
  22. */
  23. eatMethod.setAccessible(true);
  24. Object returnValue = eatMethod.invoke(studentClass.newInstance(), "狗粮");
  25. System.out.println(returnValue);
  26. } catch (NoSuchMethodException e) {
  27. e.printStackTrace();
  28. } catch (IllegalAccessException e) {
  29. e.printStackTrace();
  30. } catch (InstantiationException e) {
  31. e.printStackTrace();
  32. } catch (InvocationTargetException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }

使用反射获取内部类 — 扩展

  1. package com.powernode.p2;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.Method;
  5. public class InnerClassDemo {
  6. public static void main(String[] args) throws Exception{
  7. // test01();
  8. test02();
  9. }
  10. /*
  11. * 演示成员内部类
  12. */
  13. private static void test02() throws Exception {
  14. Class<Student> studentClass = Student.class;
  15. // 获取内部类
  16. Class<?>[] classes = studentClass.getClasses();
  17. for (Class<?> aClass : classes) {
  18. // aClass == Student$Inner
  19. // public Student$Inner(Student this$0) {}
  20. Constructor<?> constructor = aClass.getDeclaredConstructor(studentClass);
  21. Object innerObj = constructor.newInstance(studentClass.newInstance());
  22. // 调用内部类的方法
  23. Method runMethod = aClass.getDeclaredMethod("run");
  24. Object returnValue = runMethod.invoke(innerObj);
  25. System.out.println(returnValue);
  26. System.out.println("--------------------------");
  27. Field[] declaredFields = aClass.getDeclaredFields();
  28. for (Field declaredField : declaredFields) {
  29. System.out.println(declaredField);
  30. }
  31. }
  32. }
  33. /*
  34. * 演示静态内部类
  35. */
  36. private static void test01() throws Exception{
  37. Class<Student> studentClass = Student.class;
  38. // 获取内部类
  39. Class<?>[] classes = studentClass.getClasses();
  40. for (Class<?> aClass : classes) {
  41. // 调用内部类的方法
  42. Method runMethod = aClass.getDeclaredMethod("run");
  43. Object returnValue = runMethod.invoke(aClass.newInstance());
  44. System.out.println(returnValue);
  45. }
  46. }
  47. }