Java反射

java 反射二刷

网友有言:看了设计模式,SSM 框架才知道反射是干啥的,反射就是直接操作内存中的类,直接修改或者做代理模式,其实是便于机器管理这些类

反射概述:

​ 我们无法直接接触方法区中一个类的方法,属性,注解等,那就可以同过一面镜子来观察他的全貌,这个镜子就是 jdk 给我们提供的 Class 类。

(本质就是通过镜子来操作函数,类,成员)。

Class 类

​ Class 类的构造函数是私有的,不能自己构造

Class 类中有静态方法 forName()可以拿到 Class 对象

className 即为全限定名,即为完整类路径。

获取 class 对象的方法

  1. 使用类

    Class<Dog> clazz=Dog.class;
    
  2. 使用对象

    Dog dog=new dog();
    Class<? extends Dog> clazz2=dog.getClass();
    
  3. forName+全限定名称

    Class<?> clazz3=Class.forName("com.xxx.Dog");
    

不管使用上述哪一种方式来获取 Class 对象,得到的都是同一个 Class 对象,因为一个类的 Class 对象只有一个。

对 class 对象操作

//拿到一个实例。
Dog dog=clazz.newInstance();

对成员变量的操作

  1. Field[] fields=clazz.getFields();
    

可以直接拿到一个成员变量的数组,这个方法只能拿到 public 修饰的成员变量。

  1. Field[] fields=clazz.getDeclearedFields();
    

这个方法可以拿到所有的成员变量。

  1. 成员变量的本质就是赋值和取值,现在问题是给谁赋值。

    暴力注入,反射就是随便操作。

Dog dog=new Dog();
Field name=clazz.getDeclaredField("name");
//直接设置值,不能是private
name.setAccessible(true);//暴力注入,打开访问权限。
name.set(dog,"tom");
//还可以强转
String nameStr=(String) name.get(dog);

反射操作方法

  1. Method[] methods=clazz.getMethods();
    methods.getName();
    

可以直接拿到一个方法的数组,这个方法只能拿到 public 修饰的方法。

  1. Method[] methods=clazz.getDeclearedMethods();
    

这个方法可以拿到所有的方法。

  1. Method eat=clazz.getDeclearedMethod("eat");
    Method eat2=clazz.getDeclearedMethod("eat",String.class);
    

拿到一个指定的方法,第二种是方法中带有参数。

  1. 调用方法

    Dog dog=new Dog();
    eat.setAccessible(true);
    eat.invoke(dog);
    eat2.invoke(dog,"参数");
    

同理 private 方法也会涉及到爆破,进而完成调用

反射操作构造器

  1. 拿到构造器

    //获取无参构造,有参构造也同理
    Construct<Dog> construct1=clazz.getDeclearedConstruct();
    
  2. 构造器构造一个对象

    //可爆破
    Dog dog=construct1.newInstance();
    

    等同于 new Dog() or clazz.getInstance();

posted @ 2022-05-18 09:08  程序员包子  阅读(29)  评论(0编辑  收藏  举报