Java的类加载机制
一、JVM和类
运行Java:java 带有main方法的类名
启动JVM,并加载字节码。
当调用java命令来运行某个Java程序时,该命令将会启动一个JVM进程,同一个JVM中的所有线程,变量都处于同一个进程中,共享该JVM的内存区域;
当出现以下情况时JVM会退出:
1.程序正常执行结束
2.使用System.exit(0);
3.出现异常,未捕获异常;
4.平台强制结束JVM进程;
JVM进程一旦结束,该进程中内存里的数据将会丢失;
二、类的加载
当程序主动使用到某个类时,如果该类还未被加载到内存中,则系统会通过加载
、连接
、初始化
三个步骤来对该类进行初始化操作;
类的加载:
类加载是指将类的class文件(字节码文件)
载入内存中,并为之创建一个java.lang.Class
对象,我们称之为字节码对象
;
类的加载过程由类加载器(ClassLoader)
完成,类加载器通常有JVM提供,我们称之为系统类加载器
,我们也可以继承ClassLoader类
来提供自定义;
不同的类加载器可以实现加载本地字节码文件、jar包中的字节码,通过网络加载字节码等;
类的连接:
当类被加载进内存之后,系统为之生成一个对应的Class对象,接着把类二进制数据合并到JRE中;
1>验证:检测被加载的类是否有正确的内部结构;
2>准备:负责为类的static变量分配内存,并设置默认值;
3>解析:把类的二进制数据中的符号引用替换为直接引用(建议书籍《深入理解Java虚拟机》);
类的初始化:
在此阶段,JVM负责对类进行初始化,主要是对static变量
进行初始化;
类的初始化一个类包含以下几个步骤:
1>如果该类还未被加载和连接,则程序先加载并连接该类;
2>如果该类的直接父类还未被初始化,则先初始化其父类;组合关系也同理;
3>如果类中有初始化语句(静态代码块),则系统依次执行这些初始化语句;
例如:
class Demo {
static int num ;
//其底层编译后为:
static {
num = 0 ;
}
//或者我们在定义时就初始化:
static int age = 10 ;
}