Class loading and Initialization

场景

类的初始化顺序与主动引用细节(关于类的生命周期,详见参考文献)


实验

代码

/**
 * Project Name:thinkinginjava
 * File Name:Beetle.java
 * Package Name:com.sourcecode.java.util
 * Date:2016年2月20日下午12:14:22
 * Copyright (c) 2016, [email protected] All Rights Reserved.
 *
 */
package com.sourcecode.java.util;

/**
 * ClassName: Beetle <br/>
 * Reason: TODO 类的生命周期之类的初始化与主动引用 <br/>
 * 构造方法:隐性的静态方法-没有显性申明static关键字
 * 方法(包括构造方法)的执行总是在变量的初始化执行之后:
 *  1、变量l = setValue(str) 后,再执行构造方法Beetle())
 *  2、执行main方法前,先初始化staticfield 
 * 
 * date: 2016年2月20日 下午12:14:22 <br/>
 * @author Ivy Peng
 * @version 1.0
 * @since JDK 1.6
 */
public class Beetle extends Insect
{
	private int k = initialize("Beetle's field k initialized with static initializer!");
	private int l = setValue("Beetle's field l initialized with non-static initializer!!");
	private String str;
	Beetle()
	{
		System.out.println("In Beetle's constructor!");
		System.out.println("k = "+k+",j = "+j+",l = " +l +",str = " + str);
	}
	/**
	 * @param string Value to be set
	 * @return  Value
	 * @since JDK 1.6
	 */
	private int setValue(String string)
	{
		System.out.println(string);
		return 66;
	}
	private static int staticfield = initialize("Beetle's static field nitialzied!");
	
	/**
	 * TODO 测试.<br/>
	 */
	public static void main(String[] args)
	{
		System.out.println("In Beetel's main()");
		Beetle beetle = new Beetle();
	}

}

class Insect 
{
	private int i =18;
	protected int j ;
	Insect()
	{
		System.out.println("In Class Insect's Insect() constructor!");
		System.out.println("i = " + i  + ",j = " +j);
		this.j = 28;
	}
	private static int staticfield = initialize("Insect's staticfield initialized success!"); 
			
	static int initialize(String info)
	{
		System.out.println(info);
		return 8;
	}
}
执行结果
Insect's staticfield initialized success!
Beetle's static field nitialzied!
In Beetel's main()
In Class Insect's Insect() constructor!
i = 18,j = 0
Beetle's field k initialized with static initializer!
Beetle's field l initialized with non-static initializer!!
In Beetle's constructor!
k = 8,j = 28,l = 66,str = null

总结

这里以实验中的具体案例加以说明

一、类的加载

程序执行-> 访问main方法 -> 导致类的字节码Beetle.class被加载-> 加载过程中发现extends关键字 -> 导致父类Insect.class被加载。

二、类的连接

验证:当一个类被加载之后,必须要验证一下这个类是否合法,比如这个类是不是符合字节码的格式、变量与方法是不是有重复、数据类型是不是有效、继承与实现是否合乎标准等等。总之,这个阶段的目的就是保证加载的类是能够被jvm所运行。

准备:准备阶段的工作就是为类的静态变量分配内存并设为jvm默认的初值,对于非静态的变量,则不会为它们分配内存

解释:把常量池中的符号引用转换为直接引用。

三、类的初始化、对象的诞生与使用

初始化父类Insect的静态资源(Insect.staticfield = 8)-> 初始化子类Beetle的静态资源(Beetle.staticfield = 8).

以上完成了类的初始化  :->为Beetle对象的诞生做了必要的准备 ->原始变量k、l值置0;引用变量str置null

                        ->原始变量i、j 值置0(引用变量如果有的话置null,这里没有)-> 调用父类的构造方法Insect()  

                        ->Insect()方法体执行完成

                        -> Beetle()方法体执行完成 -> 至此类Beetle的对象beetle实例化完成

                        -> 准备吃饭客羡慕

注:红色标注的地方有待验证-到底是先初始化i,j的值为0,然后调用Insect(),还是先Insect(),然后置i,j = 0呢?个人偏向前者。

参考文献

1. 《thingking in java》 by Bruce Eckel.

2.  类的生命周期:http://blog.csdn.net/pengych_321/article/details/50704284


你可能感兴趣的:(Class loading and Initialization)