黑马程序员技术交流社区

标题: 静态初始化程序、构造函数 :执行顺序问题 [打印本页]

作者: sil    时间: 2013-9-21 15:51
标题: 静态初始化程序、构造函数 :执行顺序问题
本帖最后由 杨增坤 于 2013-9-22 20:56 编辑
  1. public class StaticSuper{

  2.         static {
  3.                 System.out.println("super static block");
  4.         }

  5.         StaticSuper(){
  6.                 System.out.println("super constructor");
  7.         }

  8. }



  9. public class StaticTests extends StaticSuper {

  10.         static{
  11.                 System.out.println("static block");
  12.         }

  13.         StaticTests(){
  14.                 System.out.println("constructor");
  15.         }

  16.         public static void main (String [] args){
  17.                 System.out.println("in main");
  18.                 StaticTests st= new StaticTests();
  19.         }

  20. }
复制代码


程序执行结果
super static block
static block
in main
super constructor
constructor



书上有句话说:“静态初始化程序会在构造函数之前执行”
那,我在想,程序执行 StaticTests st=new StaticTests();的时候,首先应该执行子类的静态初始化程序
就是 static{System.out.println("static block");}首先输出的应该是static block 。然后才会执行子类的构造函数StaticTests().然后子类的构造函数会先调用父类的构造函数。
我的分析的结果和实验结果不一样啊。


另外,“in main” 的输出的位置如何判断?
如果main()函数是程序的起点,是不是应该先输出“in main”呢?

求解答,新手,请轻拍^^.


20130921153935140.png (1.83 KB, 下载次数: 54)

20130921153935140.png

作者: 常在河边走_    时间: 2013-9-21 15:55
本帖最后由 常在河边走_ 于 2013-9-21 15:58 编辑

具体想问什么?
作者: sil    时间: 2013-9-21 16:01
常在河边走_ 发表于 2013-9-21 15:55
具体想问什么?

刚编辑好。
第一次编辑错了,文字全没了,只剩代码了。

作者: 常在河边走_    时间: 2013-9-21 16:21
sil 发表于 2013-9-21 16:01
刚编辑好。
第一次编辑错了,文字全没了,只剩代码了。

系统在初始化阶段执行静态初始化块是,不仅会执行本类的静态初始化块,还会一直上溯到java.lang.Object类(如果它包含静态初始化块),先执行父类的静态初始化块然后执行java.lang.Object静态初始化块,然后执行其父类的静态初始化块,最后才执行该类的静态初始化块

作者: sil    时间: 2013-9-21 16:54
常在河边走_ 发表于 2013-9-21 16:21
系统在初始化阶段执行静态初始化块是,不仅会执行本类的静态初始化块,还会一直上溯到java.lang.Object类 ...

谢谢!


对我这个程序来说:

最先执行的是 静态初始化 过程。
静态初始化会先执行父类的,再依次执行子类的。

初始化了,main()函数就开始执行了。
输出“in main“
然后开始执行构造函数。

对吧?

作者: 常在河边走_    时间: 2013-9-21 17:01
sil 发表于 2013-9-21 16:54
谢谢!

嗯嗯,是的!

作者: 曾林魁    时间: 2013-9-21 18:02
你好,Java程序要进入main方法执行程序,首先就要加载类;加载类的时候会先顺着继承链一直找到Java.lang.Object类,依次加载初始化每个父类;加载和初始化类的过程如下:


1、为父类静态属性分配内存并赋值
2、执行父类静态代码段
3、为子类静态属性分配内存并赋值
4、执行子类静态代码段

类加载完之后就能用new创建类的实例对象了;创建对象的过程如下:
1、为父类实例属性分配内存并赋值
2、执行父类非静态代码段
3、执行父类构造器
5、为子类实例属性分配内存并赋值
6、执行子类非静态代码段
7、执行子类构造器

在这个过程里面,我们会注意到两段工作都是先处理父类,然后再处理子类的。也就是子类重复了一遍父类的工作。
这个过程里面可能会遇到一个特殊现象,那就是:
1、子类覆盖了父类中的某个方法。
2、父类构造器中调用到了该方法
3、在子类中,该方法访问到了只有子类才有的属性。

作者: sil    时间: 2013-9-22 08:19
曾林魁 发表于 2013-9-21 18:02
你好,Java程序要进入main方法执行程序,首先就要加载类;加载类的时候会先顺着继承链一直找到Java.lang.Ob ...

谢谢,这回彻底明白了!





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2