详详解解JAVA类类加加载载机机制制
1.一一段段简简单单的的代代码码
首先来一段代码,这个是单例模式,可能有的人不知道 么是单例模式,我就简单说一下
单例模式是指一个类有且只有一种对象实例。这里用的是饿汉式,还有懒汉式,双检锁等等。。。。
写这个是为了给大家看一个现象
class SingleTon{
public static int count1;
public static int count2=0;
private static SingleTon instance=new SingleTon();
public SingleTon(){
count1++;
count2++;
}
public static SingleTon getInstance() {
return instance;
}
}
public class J MTest {
public static void main(String[] args) {
SingleTon.getInstance();
System.out.println(SingleTon.count1);
System.out.println(SingleTon.count2);
}
}
执行结果:
同样的代码我把private static SingleTon instance=new SingleTon()移到上面
我们再看执行结果:
可以发现执行结果发生了变化
这个先放在这,等了解了类加载机制过程,后面再说
2. 么么是是类类加加载载机机制制
概念:Java中的类加载机制指虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换、解析和初始化,
最终形成可以被虚拟机直接使用的 Java 类型。
大白话:其实就是把字节码文件放在虚拟机里面去
与那些在编译时需要进行连接工作的语言不同,在Java语言中,类型的加载、连接、初始化都是在程序运行期间完成的,这
种策略虽然会令类加载时稍微多一些性能的开销,但是会为Java应用程序提供高度的灵活性。
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用
、卸载七个阶段。验证、准备、解析被称为连接
注意:加载、验证、准备、初始化、使用、卸载这几个顺序是确定的,但是解析不一定,它在某些情况下可以在初始化阶段
后再开始,主要是为了支持Java语言运行时绑定 (只做了解即可)
类加载机制包括前面五个阶段。
3.类类加加载载时时机机
么情况下虚拟机需要开始加载一个类呢?虚拟机规范中并没有对此进行强制约束,这点可以交给虚拟机的具体实现来自由
把握。
4.类类初初始始化化时时机机
那么, 么情况下虚拟机需要开始初始化一个类呢?这在虚拟机规范中是有严格规定的,虚拟机规范指明 有且只有 五种情
况必须立即对类进行初始化 (而这一过程自然发生在加载、验证、准备之后):
遇到new 、getstatic、putstatic或invokestatic这四条字节码指令 (注意,newarray指令触发的只是数组类型本身的初始化,
而不会导致其相关类型的初始化 (比如,new String[]只会直接触发String[]的初始化,也就是触发对类j ava.lang.String 的初始化
,而直接不会触发String类的初始化)时,如果类没有进行过初始化,则需要先对其进行初始化。
生成这四条指令的最常见的Java代码场景是:
1 使用new关键字实例化对象的时候;
2 读取或设置一个类的静态字段 (被 inal修饰,已在编译器把结果放入常量池的静态字段除外)的时候;
3 调用一个类的静态方法的时候。
2) 使用j ava.lang.re lect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3) 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
4) 当虚拟机启动时,用户需要指定一个要执行的主类 (包含main()方法的那个类),虚拟机会先初始化这个主类。
5) 当使用j dk1.7动态语言支持时,