Java类加载过程

为什么说Java语言是“一处编译,到处运行”?

首先我们编写的是Java文件,经过Java编译器处理之后我们会得到一个字节码也就是.class文件,生成的这个.class文件就是可以到处运行的文件。

那么这个class文件是怎么加载到内存中的呢?先来看一张宏观图

从上图可以看出class文件是通过“类装载器”把文件加载到内存中的。其实可以一句话来解释:类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构。

那么在类加载过程中都做了哪些事?

 

什么时候才会进行类的加载?类的加载方式分为两大类

(1)隐式加载

             创建类对象

             使用类的静态域

             创建子类对象

             使用子类的静态域

             在JVM启动时,BootStrapLoader会加载一些JVM自身运行所需的class

             在JVM启动时,ExtClassLoader会加载指定目录下一些特殊的class

             在JVM启动时,AppClassLoader会加载classpath路径下的class,以及main函数所在的类的class文件

(2)显式加载

             ClassLoader.loadClass(className),只加载和连接、不会进行初始化。

             Class.forName(String name, boolean initialize,ClassLoader loader); 使用loader进行加载和连接,根据参数initialize决定是否初始化。

加载.class文件的方式:

         把一个java源文件动态编译成class文件

         或者从本地文件系统内加载class文件,

         从jar包加载class文件,

         通过网络加载class文件。

总结:

类加载后,在准备阶段就已经对类中所有变量进行了内存的分配,并赋予了初始值,之后进入到初始化阶段,优先进行静态变量的初始化(加载顺序按照代码的顺序依次执行),然后进行类变量的初始化(加载顺序按照代码的顺序依次执行)。

如果有父类的话,则先进行父类的加载,同上

举个例子

按照上述总结,从main方法入口开始执行

第一步:进行静态变量、代码块的初始化,从上到下依次执行,发现只有一个静态变量i 赋值为1

第二步:进行main方法中的代码第一行 输出1

第三步:main方法中第二行代码创建类对象,进入有参构造方法,在执行方法体内容之前。要先去执行类变量、代码块代码,从上到下依次执行,a赋值为0,代码块第一行执行得到0,第二行执行得到“打印第1次”,执行完成

第四步:进行构造方法体内的代码,得到“有参构造”。

注意要点:

静态语句块中只能访问到定义在静态语句块之前的变量,而定义在它之后的变量,在前面的静态语句块可以赋值,但不能访问,代码解释如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值