`

JAVA类加载机制

    博客分类:
  • JVM
阅读更多
虚拟机的类加载机制:
   把class文件加载到内存,并对数据进行校验、转换解析和初始化最终形成可以被JVM直接使用的类型。
java语言类加载和连接都是在程序运行期间完成的。

类加载的生命周期:加载、连接和初始化
连接又分为:验证、准备、解析三个步骤。
加载、验证、准备、初始化是确定的,解析阶段不确定,它在有些情况下在初始化之后进行。

假如加载、验证和准备完成之后,遇到以下任一情况将被初始化:
1.遇到 new,getstatic,putstatic,invokestatic(调用类的静态方法)四条字节码指令
2.使用java.lang.reflect包进行反射调用时
3.初始化一个类时如果父类没初始化,先初始化父类
4.虚拟机启动时,主类会被初始化

如下实例代码:
public class SuperClass {
	
	static{
		System.out.println("SuperClass init!");
	}
	
	public static int value=123;

}



public class SubClass extends SuperClass{

	static{
		System.out.println("SubClass init!");
	}
}


public class NotInitialization {
	
	public static void main(String[] args){
		
		System.out.println(SubClass.value);
		
	}

}


执行结果为:
SuperClass init!
123

对于静态字段只有直接定义这个字段的类才会初始化,通过子类来引用父类的静态字段只会触发父类的初始化而不会触发子类的初始化。

再看下面代码:
public class NotInitialization {
	
	public static void main(String[] args){
		//这里的字节码指令为newarray
                 SuperClass[] sca=new SuperClass[10];
	}

}

以上代码的执行结果为空,因为创建动作由字节码指令newarray触发

对于类中静态常量,编译阶段就将值存储到类的常量池中。


加载阶段JVM完成三件事:
1.通过类的全限定名定义类的字节流
2.将字节流代表的静态存储结构转化为方法区中运行的数据结构
3,在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。


验证:使用java代码无法做到访问数组边界以外的数据等
1.文件格式验证
2.元数据验证 是否有父类、是否继承了被final修饰的类等
3.字节码校验
     例如保证操作数栈中放入了int类型数据,使用时按照long来加载入本地变量表
4.符号引用验证
   将符号引用转化为直接引用

准备:
   为类变量(Static修饰的变量)分配内存并设定初始值(通常为0值)。内存分配仅包括类变量。

解析:解析阶段是虚拟机将常量池中的符号引用替换为直接引用的过程。
初始化:真正开始执行类中定义的java程序代码。

   


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics