14.反射

2022-04-29  本文已影响0人  星野君

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

一、反射案例
获取class方式:

public class Home {
  public static void main(String[] args) {

    // 第一种方式获取Class对象
    Cat cat = new Cat(); // 这一new 产生一个Student对象,一个Class对象。
    Class stuClass = cat.getClass(); // 获取Class对象
    System.out.println(stuClass.getName());

    // 第二种方式获取Class对象
    Class stuClass2 = Cat.class;

    // 第三种方式获取Class对象
    try {
      Class stuClass3 = Class.forName("com.ylf.test.Cat");
      // 注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

通过反射调用方法:

  public void Test()
      throws ClassNotFoundException, InstantiationException, IllegalAccessException,
          NoSuchMethodException, InvocationTargetException {
    Class cls = Class.forName("com.ylf.test.Cat");
    Object o = cls.newInstance();
    Method hi = cls.getMethod("xxx");
    hi.invoke(o);
  }

二、反射常用方法

  1. forName 返回指定类名name的Class对象
  2. newInstance 返回Class对象的实例
  3. getName 返回当初Class对象的名称
  4. getMethod 返回一个Method对象
  5. getDeclaredFields 返回Field对象的一个数组
  6. getClassloader 返回Class对象的加载器

三、类加载
反射加载是java实现动态语言的关键,也就是通过反射实现类动态加载

  1. 静态加载:编译时加载相关类,如果没有就则报错,依赖性太强
  2. 动态加载:运行时加载需要的类,如果运行时不用该类,即使不存在该类,也不会报错,降低了依赖性

类的加载时机:

  1. 当创建对象new时 //静态加载
  2. 当子类加载时父类也会被加载 //静态加载
  3. 调用类中的静态成员时 //静态加载
  4. 使用反射 //动态加载

类的加载过程图


image.png image.png

四、通过反射获取类的结构信息

  1. getName 获取类的全类名
  2. getSimpleName 获取简单类名
  3. getFields 获取所有public修饰的所有属性
  4. getDeclaredFields 获取所有属性
  5. getMethods 获取所有public的方法
  6. getDeclareFields 获取所有方法
  7. getConstructors 获取所有public构造器
  8. getDeclaredConstructors 获取所有构造器
  9. getPackage 返回包的信息
  10. getSuperClass 返回父类信息
  11. getInterfaces 返回接口信息

访问属性:

  public void Test()
      throws ClassNotFoundException, InstantiationException, IllegalAccessException,
          NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    Class cls = Class.forName("com.ylf.test.Cat");
    Object o = cls.newInstance();
    //访问属性
    final Field name = cls.getDeclaredField("name"); 
    name.setAccessible(true); //爆破
    System.out.println(name.get(o));
  }

通过反射创建对象:

  public void Test()
      throws ClassNotFoundException, InstantiationException, IllegalAccessException,
          NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    Class cls = Class.forName("com.ylf.test.Cat");
    Object o = cls.newInstance();
    final Constructor constructor = cls.getConstructor(String.class); // 参数是什么就对应哪个构造器
    final Object c = constructor.newInstance("小黑"); // 这里参数实参
    System.out.println(c);
  }

得到private构造器:

  public void Test()
      throws ClassNotFoundException, InstantiationException, IllegalAccessException,
          NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    Class cls = Class.forName("com.ylf.test.Cat");
    Object o = cls.newInstance();
    final Constructor constructor = cls.getDeclaredConstructor(String.class); // 参数是什么就对应哪个构造器
    constructor.setAccessible(true);//爆破
    final Object c = constructor.newInstance("小黑"); // 这里参数实参
    System.out.println(c);
  }
上一篇下一篇

猜你喜欢

热点阅读