JAVA 静态变量与非静态变量初始化顺序之新解

今天和同事争论一问题,关于静态变量与非静态变量的初始化顺序,谁先谁后,最终想整理出来!
测试代码:

import java.util.Map;

public class T {

	public static T t = new T();
	private Map map = new HashMap();
	public T(){
		System.out.println("Map的值: "+map);
	}
	public static void main(String[] args) {
		 System.out.println(t);
		 System.out.println(t.map);
	}

}

 
运行结果:
Map的值: null
cn.com.algorithm.T@de6ced
{}

为什么Map的值为null,而如果把private static Map map = new HashMap();中的static 去掉,则运行结果为:
Map的值: {}
cn.com.algorithm.T@c17164
{}
所以他觉得非静态变量是在静态变量之前初始化的,这个我太怀疑了,是这样吗?

 

 

 

下面用测试类来证明些实事:

 

public class Demo1 {
    public Demo1(){
    	System.out.println("Demo1的构造函数执行");
    }
}

 

 

public class Demo2 {
	 public Demo2(){
	    	System.out.println("Demo2的构造函数执行");
	 }
}

 

 

 

public class Demo3 {
  public Demo3(){
      System.out.println("Demo3的构造函数执行");
  }
}

 
运行(java -verbose 类名 可以看出来什么时候加载了哪些类):

D:\test>javac TestClassLoaderTime.java
D:\test>java -verbose TestClassLoaderTime > result.txt

result.txt数据片断
[Loaded TestClassLoaderTime from file:/D:/test/] 
[Loaded Demo2 from file:/D:/test/]
Demo2的构造函数执行
--------main方法开始了------------
[Loaded Demo1 from file:/D:/test/]
Demo1的构造函数执行
--------Demo1实例化过------------
[Loaded Demo3 from file:/D:/test/]
Demo3的构造函数执行
--------TestClassLoaderTime实例化过------------
[Loaded java.util.AbstractList$Itr from shared objects file]

 


说明:
1. Demo2 在 Demo1之前被类加载器加载,说明类的静态变量只有在实例化时才去加载
2. Demo3 在 Demo2 之后被类加载器加载,而且Demo3是在类TestClassLoaderTime实例化后才加载的,而Demo2是在main方法执行前被加载,说明静态变量比非静态变量先初始化!

 

 

如果修改测试类为:

public class TestClassLoaderTime {
 
   public TestClassLoaderTime(){
        System.out.println("构造器执行");
   }
   {
         System.out.println("静态代码块执行");
   }
   static Demo2 demo2 = new Demo2();
   Demo3 demo3 = new Demo3();
   public static void main(String[] args) {
          System.out.println("main方法执行");
          new TestClassLoaderTime();
          System.out.println("TestClassLoaderTime实例化过");
    }
}

 
运行结果:

 Demo2的构造函数执行
 main方法执行
 静态代码块执行
 Demo3的构造函数执行
 构造器执行
 TestClassLoaderTime实例化过

 

 说明JAVA中初始化的顺序:
 加载类、 静态成员变量初始化、 静态代码块、非静态成员变量初始化、 构造方法;

 

 

所以对于文章开头的问题,你有自己的答案了吗?

你可能感兴趣的:(java,静态,非静态,顺序)