`
hhyyllgg
  • 浏览: 27605 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

jvm类的装载过程浅析

    博客分类:
  • jvm
 
阅读更多
jvm将类的装载过程分为3个步骤:装载,链接,初始化。而链接过程又分为:效验,准备,解析(可选)
1,装载
  负责找到二进制字节码并加载至jvm,jvm通过类的全限定名及类的加载器完成类的加载
2,效验
  对二进制字节码的格式进行效验
3,准备
  jvm为类变量分配内存,并设置默认初始值(譬如 reference设置为null boolean设置为false)
4,解析(可选)
  在类的常量池中寻找类,接口,字段,方法的符号引用,并把它替换为直接引用,在符号引用被程序首次主动使用之前,解析这个步骤是可选的
5,初始化
  为了准备让一个类或者接口首次主动使用,就要为类变量赋予正确的值(注意哦:是正确的值,不是默认值)。
  什么是主动使用呢?6种活动被认为是主动使用
 
  •    (1) 调用了new。
  •    (2) 调用了类中的静态方法。
  •    (3) 调用了类中的非常量的静态字段。
  •    (4) 反射。
  •    (5) 子类的初始化方法。
  •    (6) jvm启动过程中指定的初始化类。

其中对于非常量的静态字段的调用还有一个条件是只有当类或者接口中的确声明了这个字段才被认为是主动使用,而对于子类或者实现接口调用父类的非常量的静态字段被认为是被动使用,不会触发初始化。如下:
public class Parent {

	
		static int parent=(int) (Math.random()*3.0);
		static {
			System.out.println("老子出生了!!!");
		}
}

public class Baby extends Parent {
	
	static int baby=(int) (Math.random()*6.0)+2;
	static {
		System.out.println("老子经过不懈的努力,儿子也出生了~!!!");
	}
}

public class Test {

	
		public static void main(String[] args) {
			int test=Baby.parent;
			System.out.println(test);
		}
		static{
			System.out.println("见证人上帝出世了!!!");
		}
}


结果为:
见证人上帝出世了!!!
老子出生了!!!
1


parent是类Parent的非常量静态字段,Baby.parent触发了Parent的初始化,而Baby没有被初始化,也没有被加载。

而对于final static的字段,使用这样的字段,也不触发初始化
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics