Java的反射机制、构造方法

1.反射的概念

​ 反射是一种机制,可以在程序运行期间,去调用类中的各种成员。(构造方法,变量,方法)

2.获取字节码对象的三种方式
  • 使用对象调用getClass()方法

  • 使用类名.class

  • 使用Class.forName()静态方法

  • 代码演示

public class Demo01获取字节码对象 {
    public static void main(String[] args) throws ClassNotFoundException {
          //每一个类被加载进内存就会有一个唯一的字节码对象,字节码对象的类型是Class类型
  
          //- 使用对象调用getClass()方法
          Class c1 = "abc".getClass();
  
          //- 使用类名.class
          Class c2 = String.class;
  
          //- 使用Class.forName()静态方法
          //参数里面要写的是类的全类名 包名+类名
          Class c3 = Class.forName("java.lang.String");
  
          System.out.println(c1 == c2);//true
          System.out.println(c2 == c3);//true
      }
  }
3.反射操作构造方法
  • 反射获取构造方法
    • Class类可以调用:
      • getConstructor(Class… c) 可以获取某一个构造方法(公共的)
      • getConstructors() 可以获取所有的构造方法(公共的)
public class Demo03反射操作构造方法 {
    public static void main(String[] args) throws Exception {
        //获取类的字节码对象
        Class c = Class.forName("com.demo.Student");

        //获取构造方法
        //getConstructor(Class... c)  :获取某一个构造方法
        //()什么都不写代表获取空参构造
        Constructor con = c.getConstructor();
        System.out.println(con);

        //()写参数可以获取有参构造
        Constructor con2 = c.getConstructor(String.class, int.class);
        System.out.println(con2);


        //getConstructors() :获取所有的公共的构造方法
        Constructor[] cons = c.getConstructors();
        //打印数组
        System.out.println(Arrays.toString(cons));
    }
}
  • 反射执行构造方法

    • Constructor类可以调用:

      • newInstance(Object… obj) : 执行当前构造方法创建对象。

        ​ Object… obj 表示的是创建对象时的实际参数。

public class Demo04构造方法的执行 {
    public static void main(String[] args) throws Exception {
        //获取类的字节码对象
        Class c = Class.forName("com.demo.Student");

        //getConstructor(Class... c)  :获取某一个构造方法
        //()什么都不写代表获取空参构造
        Constructor con = c.getConstructor();

        //执行构造方法,可以真正创建出对象
        //newInstance(Object... obj) :让构造方法执行
        Student s1 = (Student) con.newInstance();
        System.out.println(s1);


        //()写参数可以获取有参构造
        Constructor con2 = c.getConstructor(String.class, int.class);

        //执行这个有参构造,创建对象
        //参数Object... obj  代表的是构造方法的实际参数
        Student s2 = (Student) con2.newInstance("柳岩", 36);
        System.out.println(s2);

    }
}
4.反射操作成员方法
  • 反射获取成员方法

    • Class类中的方法:

      • getMethod(String name, Class… c) :获取一个成员方法(公共的)

        ​ String name 表示方法名称

        ​ Class… c 表示的是方法的参数的类型

      • getMethods() : 获取类中的所有方法(公共的)

 public class Demo01反射获取成员方法 {
      public static void main(String[] args) throws Exception {
          //获取字节码对象
          Class c = Class.forName("com.demo.Student");
  
          //获取类中的成员方法
          //getMethod(String name,Class... c) :获取某一个成员方法(公共的)
          //获取睡觉的方法
          Method m1 = c.getMethod("sleep");
          System.out.println(m1);
  
          //获取吃饭方法
          Method m2 = c.getMethod("eat", String.class);
          System.out.println(m2);
  
          //getMethods()  :获取所有的成员方法(公共的)
          Method[] methods = c.getMethods();
          //打印数组
          System.out.println(Arrays.toString(methods));
  
      }
  }
  • 反射执行成员方法

    • Method类可以调用:

      • Object invoke(Object obj , Object… o) :让方法执行

        ​ 第一个参数表示执行的对象

        ​ 第二个参数表示方法的实际参数

        ​ 返回值表示方法的实际返回值

  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  
  public class Demo02反射执行成员方法 {
      public static void main(String[] args) throws Exception {
          //获取字节码对象
          Class c = Class.forName("com.demo.Student");
  
          //创建对象
          Constructor con = c.getConstructor();
          Student stu = (Student) con.newInstance();
  
          //获取睡觉的方法
          Method m1 = c.getMethod("sleep");
  
          // invoke(Object obj,Object... parm): obj表示要执行方法的对象   parm表示的是执行方法的实际参数
          //执行睡觉方法
          m1.invoke(stu);
  
          //获取吃饭方法
          Method m2 = c.getMethod("eat", String.class);
          //执行吃饭方法
         m2.invoke(stu, "玉米");
      }
  }
5.暴力反射

​ 上面反射获取内容时,只能获取公共的内容,可以使用暴力反射获取任意的内容;

​ 在使用反射的时候,有加了Declared的方法,这些方法都叫做暴力反射

​ 在暴力反射获取到内容之后,需要调用 setAccessable(true)设置权限true表示允许使用

public class Demo03暴力反射 {
    public static void main(String[] args) throws Exception {
        //获取字节码对象
        Class c = Class.forName("com.demo.Student");

        //获取构造方法
        //暴力反射 就是在方法中间加一个词Declared,就可以获取任意权限的内容
        Constructor con = c.getDeclaredConstructor();
        System.out.println(con);
        //设置权限
        con.setAccessible(true);
        //创建对象
        Student s = (Student) con.newInstance();
        System.out.println(s);

        //----------------------------------------

        //暴力反射获取方法
        Method m = c.getDeclaredMethod("study");
        //设置权限
        m.setAccessible(true);
        //执行学习的方法
        m.invoke(s);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值