如何加载class文件

本文深入探讨Java中的ClassLoader机制,包括其加载过程中的关键步骤:字节码加载、验证与解析,以及初始化。同时介绍了如何通过URLClassLoader加载外部资源,并对比了显式与隐式加载的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇ClassLoader的基础知识中提到,类加载器第一个作用就是加载Class到JVM中,其实就是加载jar文件中的.class文件和javac编译.java生成的.class文件。

ClassLoader加载一个class文件到JVM时需要经过以下几个步骤:

    1.找到.class文件并把这个文件包含的字节码加载到内存中。

    2.第二个阶段分为三个步骤,分别是字节码验证、Class类数据结构分析及相应的内存分配和最后的符号表的链接

    3.类中静态属性和初始化赋值,以及静态块的执行等。

加载字节码到内存:

    抽象类ClassLoader并没有定义如何去加载,如何去找到指定类并且把它的字节码加载到内存需要的子类中实现,也就是要实现findClass()方法。URLClassLoader就是ClassLoader一个子类。从名字就能知道,它是通过一个“URL”来找到要加载的字节码。在URLClassLoader中通过一个URLClassPath类帮助取得要加载的class文件字节流(找到这个class文件,再读取它的byte字节流,通过调用defineClass()方法来创建类对象),URLClassLoader的构造函数接收一个URL的参数创建。这样就可以用这个URL来创建URLClassPath,在创建URLClassPath对象时会根据传过来的URL数组中的路径来判断是文件还是jar包,根据路径不同分别创建FileLoader或者JarLoader,或者使用默认的加载器。当JVM调用findClass时由这几个加载器来将class文件的字节码加载到内存中。

验证与解析:

    1.字节码验证,类装入器对于类的字节码要做许多检测,以确保格式正确、行为正确。

    2.类准备,准备代表每个类中定义的字段、方法、和实现接口所必需的数据结构。

    3.解析,类装入器装入类所引用的其他所有类。可以用许多方式引用类,如超类、接口、字段、方法签名、方法中使用的本地变量

初始化Class对象

    在类中包含的静态初始化器都被执行,在这一阶段末尾静态字段被初始化为默认值。


从解析步骤中,我们可以知道加载class文件到内存不一定要直接指定.class文件或.jar的URL(使用IDE可能会忽略这点,认为并没有指定什么classpath。如果你使用过记事本编写HelloWorld.java,然后在命令行使用javac,java的命令来编译和执行程序,你就会知道你是需要路径的)。JVM加载class文件到内存由两种方式:

1.隐式加载:所谓隐式加载就是不通过在代码里调用ClassLoader来加载需要的类,而是通过JVM来自动加载需要的类到内存的方式。例如,我们在类中继承或者引用了某个类时,JVM在解析当前这个类时发现引用的类不在内存中,那么就会自动将这些类加载到内存中。

2.显示加载:相反的显示加载就是我们在代码中调用ClassLoader类来加载一个类的方式,例如:调用

this.getClass.getClassLoader().loadClass()
或者Class.forName(),或者我们自己实现的ClassLoader的findClass()方法等。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值