java虚拟机之初始化

类从加载到内存虚拟机内存开始,到卸载出内存为止,整个生命周期是:加载,验证,准备,解析,初始化,使用,卸载。
加载,验证,准备,初始化,卸载。这五个阶段的顺序是固定的。类的加载过程必须按照这种过程进行,但解析就不一定了。在某些情况下可以在初始化后再开始。这是为了支持java的动态绑定。注意的是这几个阶段不是一个阶段结束了才会执行下一阶段。有可能是这一阶段执行过程中,下一阶段也开始执行了。
java虚拟机中对加载没有进行强制约束。但对于初始化阶段有且只有一下四种情况必须立即对类进行初始化(之前的几个阶段在此之前开始)
1,遇到new,getstatic,putstatic,和invokestatic这四条字节码指令时,如果类没有初始化,则必须进行初始化。
2,使用java.lang.reflet包的方法对类进行调用的时候。
3,当初始化一个类的时候,如果发现其父类没有进行初始化,则其父类要初始化。
4,当虚拟机启动时,用户需要指定一个要执行的主类(包括main())虚拟机会先进行初始化这个类
例1:
public class SuperClass{
static{
System.out.println("SuperClass init");
}
public static int vlaue = 123;
}
public class SubClass extends SuperClass{
static {
System.out.println("SubClass init");
}
}

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


上面只会输出“SuperClass init”
原因:对于静态字段,只有直接定义这个类才会被初始化,通过子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。
例2:
public class NotInit{
public static void main(String args[]){
SuperClass sc = new SuperClass[10];
}
}

没有输出“SuperClass init”。
例3:
public class ConstClass{
static {
System.out.println("ConstClass init")
}
public static final String HELLOWORLD = "hello world";
}
public class NotInit{
public static void main(String args[]){
System.out.println(ConstClass.HELLOWORLD);
}
上面也不会输出“ConstClass init”
原因:虽然java源码中引用了ConstClass类中的常量HELLOWORLD但是在编译阶段将次常量的值“helloworld”存储到了NotInit类的常量池中,之后只对自己类中的常量池进行了引用。两个类在编译成class文件后就不存在任何联系了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值