JAVA类的初始化顺序(静态变量,静态模块,变量,模块,构造器)
???????????对于静态变量,与类变量及构造器初始化顺序的朋友们,大家看过来了,阅读了以后几段代码之后,你会发现原来也就是这么简单.先看下面这几个类.
??
/**类A**/public class TestA { public TestA(String a){ System.out.println(a); }}/**类B**/public class TestB { public TestB(String b){ System.out.println(b); }}/**类 Parent **/public class Parent { private static TestA testA1 = new TestA("Parent的静态变量"); static { System.out.println("Parent的静态初始化模块"); } private TestA testA2 = new TestA("Parent变量"); { System.out.println("Parent的初始化模块"); } public Parent(){ System.out.println("Parent的构造函数"); }}/**Parent的子类SubClass**/public class SubClass extends Parent{ private static TestA testA1 = new TestA("SubClass的静态变量1"); static { System.out.println("SubClass的静态初始化模块1"); } private static TestA testA2 = new TestA("SubClass的静态变量2"); static { System.out.println("SubClass的静态初始化模块2"); } private TestA testA3 = new TestA("SubClass变量1"); { System.out.println("SubClass的初始化模块1"); } private TestA testA4 = new TestA("SubClass变量2"); { System.out.println("SubClass的初始化模块2"); } public SubClass(){ System.out.println("SubClass的构造函数"); } public static void main(String[] args) { SubClass subClass = new SubClass(); }}?
打印结果如下:
??? Parent的静态变量
??? Parent的静态初始化模块
??? SubClass的静态变量1
??? SubClass的静态初始化模块1
??? SubClass的静态变量2
??? SubClass的静态初始化模块2
??? Parent变量
??? Parent的初始化模块
??? Parent的构造函数
??? SubClass变量1
??? SubClass的初始化模块1
??? SubClass变量2
??? SubClass的初始化模块2
??? SubClass的构造函数
?说明?:
1.静态变量与静态模块是最先初始化的,因为它是属于类的变量和模块.
2.Parent的构造器要先于它的子类,这一点是肯定的,但Parent的变量,初始化模块要先于它的子类,这一点可能理解起来有点困难,但我们只要知道父类的构造器先于子类,它的变量与模块也是理所当然的,这样理解起来会比较合理.
3.静态变量与静态模块的初始化顺序是根据在类里面定义的顺序,同理变量化初始化模块的顺序也是根据类里面定义的顺序(上面结果的红色部门)
1 楼 C_J 2009-04-17 我觉得你的总结有些偏差1.静态变量与静态模块是最先初始化的,因为它是属于类的变量和模块.
原因我觉得是 它是属于进程的静态常量区,他的范围应该不能以“类”来划分
2.Parent的构造器要先于它的子类,这一点是肯定的,但Parent的变量,初始化模块要先于它的子类,这一点可能理解起来有点困难,但我们只要知道父类的构造器先于子类,它的变量与模块也是理所当然的,这样理解起来会比较合理.
构造器可能涉及到类变量操作,所以既然先初始化了父类的构造器,那父类的成员变量也当然要先构造 2 楼 行者买刀 2009-04-17 C_J 写道我觉得你的总结有些偏差
1.静态变量与静态模块是最先初始化的,因为它是属于类的变量和模块.
原因我觉得是 它是属于进程的静态常量区,[color=red]他的范围应该不能以“类”来划分[/color]
2.Parent的构造器要先于它的子类,这一点是肯定的,但Parent的变量,初始化模块要先于它的子类,这一点可能理解起来有点困难,但我们只要知道父类的构造器先于子类,它的变量与模块也是理所当然的,这样理解起来会比较合理.
构造器可能涉及到类变量操作,所以既然先初始化了父类的构造器,那父类的成员变量也当然要先构造
1.静态变量与静态模块放在静态区没错的,而且是放在java的线程栈中,每个java独立的线程都有自己的栈,并且它们不是线程安全的,
"他的范围应该不能以“类”来划分"这句话,我想理解有些偏差了,如果它不以类划分的话,那么怎么去调用它,它不像C++那样属于全局变量,可以直接引用,它必须属于某个类中的静态变量,我们调用它也是用Class.param才能得到它.并且,在没有用到它的时候,它是不会被初始化的,只有在你引用到它的时候,它才会被初始化并且放中线程栈中.
2.第二点你的理的理解不错的,支持下. 3 楼 C_J 2009-04-17 “放在java的线程栈中,每个java独立的线程都有自己的栈”
你的意思是 你这里的 静态变量和模块 是放在某个线程栈么???
或者是某个“类的常量区”么? 4 楼 行者买刀 2009-04-17 C_J 写道“放在java的线程栈中,每个java独立的线程都有自己的栈”
你的意思是 你这里的 静态变量和模块 是放在某个线程栈么???
或者是某个“类的常量区”么?
我想先问你两个问题:
一是你觉得静态变量是放在栈里还是堆里?
二是你觉得类的常量与类的静态变量有区别吗,区别是什么.
5 楼 C_J 2009-04-17 恩 我和C++混了
1,
局部静态变量放到STACK
全局静态变量在全局区(而JAVA没有全局静态变量这个说法了)
2,
有,常量不可改变 静态变量不可“运行赋值”