基础-11-反射

1、类加载
当程序要使用某个类时,如果该类还未被加载到内存中,系统则会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化,如果不出现意外情况,JVM将会连续完成这三个步骤,这三个步骤被称为类加载或类初始化。
类的加载:
把class文件读入内存,并创建java.lang.Class对象。任何类被使用时,系统都会为之建立一个java.lang.Class对象。
类的连接;
验证阶段:检验被加载的类是否有正确的内部结构,并和其他类协调一致。
准备阶段:负责为类变量分配内存,并设置默认值。
解析阶段:把类的二进制数据中的符号引号替换为直接引用。
类的初始化:主要是是对类变量进行初始化。
类的初始化步骤:
假如还未被加载和连接,则程序先加载并连接该类。
假如该类的直接父类还未被初始化,则先初始化其直接父类。
假如类中有初始化语句,则一次执行这些初始化语句。
类的初始化时机:
创建类的实例。
调用类的方法。
访问类或接口的类变量,或者为类变量赋值。
使用反射方式强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令运行某个类。

2、类加载器
2.1、类加载器的作用:
负责将.class文件加载到内存中,并生成java.lang.Class对象。

2.2、JVM类加载机制
全盘负责:就是当一个类加载器负责加载某一个类时,该类所依赖和所引用其他类也有该类加载器负责载入,除非显示使用另一个类加载器来载入。
父类委托:当一个类加载器负责加载某个class时,先让付类加载器试图加载该class,只有父类加载器无法加载时,才尝试从自己的类路径中加载该类。
缓存机制:先从缓存区中搜索该class,不存在则读取二进制数据,转换为class对象,存储到缓存中。

2.3、类加载器
ClassLoader:是负责加载类的对象
ClassLoader loader = ClassLoader.getSystemClassLoader()
Bootstrap类加载器:虚拟机的内置类加载器
Platform class loader 平台类加载器
System class loader 应用程序类加载器

3、反射
3.1、反射:是指在运行时去获取一个类的变量和方法信息,然后通过获取到的信息创建对象,调用方法的一种机制。

3.2、获取Class类的对象
第一种:使用类的class属性得到Class对象。
Class c1 = Student.class;
Class c1 = Student.class;
sout(c1 == c2) //返回true

第二种:调用对象的getClass()方法
Student stu = new Student();
Class<? extends Student> c3 = stu.getClass(); sout(c1 == c3) //返回true 第三种:使用class中的静态方法forName(String className) Class<?> c4 = Class.forName(“com.test.Student”);

3.3、反射获取构造方法并使用
Class<?> c4 = Class.forName(“com.test.Student”);

Construtor<?>[] cons = c4.getConstructors();//只能拿到公共的构造方法

Construtor<?>[] cons2 c4.DeclaredConstrutos();//拿所有的构造方法

Construtor cons = c4.getConstructor(参数类型的字节码类型…)
//返回单个公共构造方法

Construtor cons = c4.getDeclaredConstructor(参数类型的字节码类型…)
//返回单个构造方法,可以是私有的

3.4、反射创建对象的过程
Class<?> c4 = Class.forName("com.test.Student"); Construtor<?> con = c4.getConstructor();
Object obj = con.newInstance();
测试代码为:

        Class<?> c = Class.forName("com.learn.day20220419.Student");
        Constructor<?> con = c.getDeclaredConstructor(String.class, Integer.class);
        //1.获取普通构造法方法,直接创建对象
        Object stu = con.newInstance("zhangsan", 22);
        System.out.println(stu);
        //2.获取私有的构造方法,暴力创建对象
        Constructor<?> con2 = c.getDeclaredConstructor(String.class);
        con2.setAccessible(true);//私有方法需要设置,不然创建对象会报错
        Object stu2 = con2.newInstance("lisi");
        System.out.println(stu2);

4、获取字段
4.1、获取所有公共的字段,返回一个数组
Class<?> c = Class.forName(“com.learn.day20220419.Student”);
Field[] fields = c.getFields();
4.2、获取所有字段,返回一个数组
Field[] declaredFields = c.getDeclaredFields();
4.3、获取指定一个公共字段
4.4、获取一个指定字段

5、笔记

        //1、获取所有公共构造方法
        System.out.println("1、获取所有公共构造方法--------------------------------------");
        Class<?> c = Class.forName("com.yan.test.Student");
        Constructor<?>[] cons = c.getConstructors();
        Stream.of(cons).forEach(con -> System.out.println(con));

        //2、获取所有构造方法,包括私有构造
        System.out.println("2、获取所有构造方法,包括私有构造-------------------------------");
        cons = c.getDeclaredConstructors();
        Stream.of(cons).forEach(con -> System.out.println(con));

        //3、根据参数类型获取指定公共构造方法
        System.out.println("3、根据参数类型获取公共构造方法--------------------------------");
        Constructor<?> con = c.getConstructor(String.class, Integer.class, String.class);
        System.out.println(con);

        //4、根据参数类型获取指定构造方法,包括私有方法
        System.out.println("4、根据参数类型获取指定构造方法,包括私有方法---------------------");
        con = c.getDeclaredConstructor(String.class, Integer.class);
        System.out.println(con);

        //5、通过构造方法给对象赋值
        System.out.println("5、通过构造方法给对象赋值--------------------------------------");
        con = c.getDeclaredConstructor(String.class, Integer.class, String.class);
        con.setAccessible(true);
        Object obj = con.newInstance("zhangsan", 20, "wuhan");
        System.out.println(obj);

        //6、获取所有公共字段
        System.out.println("6、获取所有公共字段----------------------------------------------");
        Field[] fields = c.getFields();
        Stream.of(fields).forEach(field -> System.out.println(field));

        //7、获取所有字段,包括私有
        System.out.println("7、获取所有字段,包括私有-----------------------------------------");
        fields = c.getDeclaredFields();
        Stream.of(fields).forEach(field -> System.out.println(field));

        //8、获取指定公共字段
        System.out.println("8、获取指定公共字段----------------------------------------------");
        Field addressField = c.getField("address");
        System.out.println(addressField);

        //9、获取指定字段,包括私有
        System.out.println("9、获取指定字段,包括私有------------------------------------------");
        Field nameField = c.getDeclaredField("name");
        System.out.println(nameField);

        //10、给字段赋值
        System.out.println("10、给字段赋值--------------------------------------------------");
        //先创建一个对象
        Class<?> c2 = Class.forName("com.yan.test.Student");
        Constructor<?> con2 = c2.getDeclaredConstructor();
        con2.setAccessible(true);
        Object obj2 = con2.newInstance();
        //获取字段
        Field nameField2 = c2.getDeclaredField("name");
        nameField2.setAccessible(true);
        nameField2.set(obj2, "zhangsan");
        //取出字段的值
        System.out.println(nameField2.get(obj2));

        //11、获取所有公共方法,包含集成和实现的方法
        System.out.println("11、获取所有公共方法,包含集成和实现的方法---------------------------");
        Method[] methods = c.getMethods();
        Stream.of(methods).forEach(method -> System.out.println(method));

        //12、获取所有方法,只是本类中的方法,不包含集成和实现的方法
        System.out.println("12、获取所有方法,只是本类中的方法,不包含集成和实现的方法---------------");
        methods = c.getDeclaredMethods();
        Stream.of(methods).forEach(method -> System.out.println(method));

        //13、获取指定公共方法
        System.out.println("13、获取指定公共方法----------------------------------------------");
        Method show1Method = c.getMethod("show1");
        System.out.println(show1Method);

        //14、获取指定方法,包括私有
        System.out.println("14、获取指定方法,包括私有-----------------------------------------");
        Method show2Method = c.getDeclaredMethod("show2", String.class);
        System.out.println(show2Method);

        //15、调用方法
        System.out.println("15、调用方法----------------------------------------------------");
        //创建对象
        Class<?> c3 = Class.forName("com.yan.test.Student");
        Constructor<?> con3 = c3.getDeclaredConstructor(String.class, Integer.class, String.class);
        con3.setAccessible(true);
        Object obj3 = con3.newInstance("zhangsan", 20, "wuhan");
        //获取方法
        Method show2Method3 = c3.getDeclaredMethod("show2", String.class);
        show2Method3.setAccessible(true);
        show2Method3.invoke(obj3, "nike");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值