当前位置:首页 > 开发 > 编程语言 > Java > 正文

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

发表于: 2012-12-28   作者:周凡杨   来源:转载   浏览:
摘要: 今天和同事争论一问题,关于静态变量与非静态变量的初始化顺序,谁先谁后,最终想整理出来!测试代码: import java.util.Map; public class T { public static T t = new T(); private Map map = new HashMap(); public T(){ System.out.println(&quo

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

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 静态变量与非静态变量初始化顺序之新解

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
初始化块与构造方法的作用很相似,他们都用于对Java对象执行指定的初始化块操作,但两者之间仍然存
public class StaticVariable { public static void main(String[] args) { Person p1 = new Person
PHP中的变量作用范围的一个重要特性就是静态变量(static 变量),仅在局部函数域中存在且只被初始
静态变量 静态变量的类型说明符是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式
java类的成员变量有俩种:一种是被static关键字修饰的变量,叫类变量或者静态变量;另一种没有static
java类的成员变量有俩种:一种是被static关键字修饰的变量,叫类变量或者静态变量;另一种是实例变
java类的成员变量有俩种:一种是被static关键字修饰的变量,叫类变量或者静态变量;另一种没有stati
使用Intent可以很方便在不同activity之间传递数据,这个也是官方推荐的方式,但是也有一定的局限性
#include <iostream> using namespace std; int main() { int * np; int i = 2; while(i--) {
Android是用Java开发,其静态变量的生命周期遵守Java的设计。我们知道静态变量是在类被load的时候分
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号