JAVA中类的加载及对象初始化顺序

      前段时间在做单例的时候遇到一个很奇怪的问题,前面已经初始化的参数,已经有值了,但是等到对象建立却发现值却为null了,随便debug跟踪下看看到底是怎么回事。

   

   解释示例代码如下

public class Demo {
	private static int i=0;
	private static  String msg ="";
	private static Demo d=new Demo();//这样写确实很怪异,只是为说明顺序而写在这里
	
    private static  String DRIVER=null;
	
	private static  String URL=null;
	
	private static  String USERNAME=null;
	
	private static  String PASSWORD=null;
	
	private   String demoString="abc";
	
	static{
		System.out.print("执行了类的静态块,在类的静态块里面为USERNAME赋值----");
		USERNAME="USERNAME";
		//do something
		System.out.print("类加载时,因DRIVER在d后声明,后经DRIVER声明后值为"+DRIVER);//此时DRIVER值为null
		System.out.print("   USERNAME为:"+USERNAME+"--------");//USERNAME为USERNAME
		System.out.println("类加载时不对非静态的属性进行加载,因此demoString在此不可用");
		//System.out.println(demoString);类加载时不对非静态的属性进行加载,因此demoString在此不可用
	}
	
	public Demo(){
		System.out.print("调用了构造函数,在构造函数中为DRIVER赋值------");
		DRIVER="DRIVER";
		//do something
		i++;
		if(i==1) msg="类加载初始化属性时,因声明d是一个Demo对象调用了构造函数因此";
		else msg="产生对象时,因类加载时已经执行过USERNAME初始化,且产生对象又调用了构造函数,因此";
		
		System.out.print(msg+"DRIVER为:"+DRIVER);//此时DRIVER值为DRIVER
		System.out.print("   USERNAME为:"+USERNAME+"-----");//USERNAME为null
		
		System.out.println("构造函数时对象开始产生,非静态的属性被解释"+demoString);//构造函数时对象开始产生,非静态的属性被解释
	}
	
	public String test() {
		//do something 类加载和产生对象时不会执行,当调用时才执行
		return null;
	}
	
	public static String test1() {
		//do something 类加载和产生对象时不会执行,当调用时才执行
		return null;
	}
}

   测试代码

 

public class XmlMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
                              Demo dd=new Demo();
       }
}

打印结果:

调用了构造函数,在构造函数中为DRIVER赋值------类加载初始化属性时,因声明d是一个Demo对象调用了构造函数因此DRIVER为:DRIVER   USERNAME为:null-----构造函数时对象开始产生,非静态的属性被解释demoString=abc
执行了类的静态块,在类的静态块里面为USERNAME赋值----类加载时,因DRIVER在d后声明,后经DRIVER声明后值为null   USERNAME为:USERNAME--------类加载时不对非静态的属性进行加载,因此demoString在此不可用
调用了构造函数,在构造函数中为DRIVER赋值------产生对象时,因类加载时已经执行过USERNAME初始化,且产生对象又调用了构造函数,因此DRIVER为:DRIVER   USERNAME为:USERNAME-----构造函数时对象开始产生,非静态的属性被解释demoString=abc

 

 

上面的代码基本上可以展示一个类从加载到产生对象的先后顺序,类加载时:静态属性顺序执行到静态代码块,产生对象时按非静态属性到执行构造函数顺序执行,至此一个对象完整产生。

你可能感兴趣的:(java)