Java类加载器、反射机制

类加载的过程

.java文件编译后产生.class字节码文件,放在磁盘。

加载

根据包名+类名在磁盘种找到这个字节码文件;

创建输入流;

把字节码文件读取到内存;

读到内存后不能随便放,在内存中创建一个java.lang.Class对象保存该类的信息。

假设类中有String型成员,这时候不知道String类加载了没、如果加载了放在哪,因此这里的String用符号代替

验证

检查文件信息是否符合当前虚拟机规范、会不会危害虚拟机自身安全;

准备

为静态变量分配内存,并初始化一个默认值;(是默认值0、null等)

解析

将类的二进制流中的符号引用替换为直接引用:(简单概括:如果用到其他类(包括继承父类),此时就要找到对应的类,没有就加载)

Class对象分配到地址0x0011,记录的信息中有String引用数据类型变量;

在第一步加载Student类的时候,String类加载了没有,如果加载了Class对象在哪里,我们不知道,因此这里的String引用是符号引用。

到解析这一步时,就会实际地去找String类在哪里,把符号换成String类的实际地址0x0022。

初始化

根据程序员在程序中制定的主观计划去初始化静态变量和其他资源:

这里就是静态成员实例化、静态块执行的时机。

 

类加载器的分类

每一种类加载器加载什么样的字节码文件都由JVM指定好了。

 

这里的子父类关系不是代码指定的extends关系,只是逻辑上的:

当调用子加载器加载某字节码文件时,子加载器不会直接加载,而是先调用父加载器加载它,如果得知父加载器加载不了,才自己加载。

获取三种类加载器并打印:

启动类加载器以null显示:

类加载器常用方法(都定义在ClassLoader类中):

类加载器加载资源一般用于加载配置文件:

注意:类加载器的getRescouceAsStream()参数是相对路径时,相对的是项目的src目录(IO流中是相对于项目根目录)。

 

 

反射

注意:利用反射调用类中的属性和方法时,无视访问修饰符。

获取Class对象的三种方式:

获取构造方法:

获取全部public构造方法:

获取全部构造方法:

获取单个构造方法:

单个构造同样也分Declared:

注意:获取构造方法Declared的区别是能获取private构造。

获取构造方法的参数类型:

反射创建实例:

通过构造方法创建实例:

通过私有静态方法创建实例:(private成员用反射机制调用时要先设置可访问)

Class对象直接创建实例(JDK10中已过时):

反射获取类的成员属性:

注意:获取成员属性Declared区别是可以获取private属性。

获取成员属性的信息:

反射为实例赋值:

注意:set()方法强行取消访问权限检查,不安全,不建议用。如果要用,应该在用完后把访问权限改回来。

建议通过反射调用setter方法来给属性赋值。

反射获取实例某属性的值:

反射获取类的成员方法:

注意:获取成员方法Declared区别是可以获取private方法、可以过滤掉父类方法。

反射运行类的成员方法:

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值