前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java初始化顺序

Java初始化顺序

作者头像
java达人
发布2018-01-31 15:55:28
5870
发布2018-01-31 15:55:28
举报
文章被收录于专栏:java达人java达人java达人

作者:wota

来源:http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html(点击文末阅读原文前往)

1 无继承情况下的Java初始化顺序:

class Sample

{
      Sample(String s)
      {
            System.out.println(s);
      }
      Sample()
      {
        System.out.println("Sample默认构造函数被调用");
      }
}

class Test{

 static Sample sam=new Sample("静态成员sam初始化");
      Sample sam1=new Sample("sam1成员初始化");
 static{
            System.out.println("static块执行");
 if(sam==null)System.out.println("sam is null");
            sam=new Sample("静态块内初始化sam成员变量");
            }
      Test()
      {
            System.out.println("Test默认构造函数被调用");
      }
}

//主函数

 public static void  main(String  str[])
{
     Test a=new Test();
 }

输出结果为:

静态成员sam初始化 -----静态成员初始化

static块执行 -----静态块被执行

静态块内初始化sam成员变量 ----静态块执行

sam1成员初始化 -----普通成员初始化

Test默认构造函数被调用 -----构造函数执行

由此可以得出结论:

a 静态成员变量首先初始化(注意,Static可以看做一个静态成员,其执行顺序和其在类中申明的顺序有关)

b 普通成员初始化

c 执行构造函数。

对于静态成员(static块可以看成普通的一个静态成员,其并不一定在类初始化时首先执行)和普通成员,其初始化顺序只与其在类定义中的顺序有关,和其他因素无关。

例如下面的例子:

class Test{
 static{
            System.out.println("static 块 1  执行");
            }
 static Sample staticSam1=new Sample("静态成员staticSam1初始化");
      Sample sam1=new Sample("sam1成员初始化");
 static Sample staticSam2=new Sample("静态成员staticSam2初始化");
 static{
            System.out.println("static 块 2  执行");
            }
      Test()
      {
            System.out.println("Test默认构造函数被调用");
      }
      Sample sam2=new Sample("sam2成员初始化");
}

则结果为:

static 块 1 执行

静态成员staticSam1初始化

静态成员staticSam2初始化

static 块 2 执行

--------静态成员

sam1成员初始化

sam2成员初始化

--------普通成员

Test默认构造函数被调用

--------构造函数

2 Java继承情况下的初始化顺序:

class Test{
 static{
            System.out.println("父类static 块 1  执行");
            }
 static Sample staticSam1=new Sample("父类 静态成员staticSam1初始化");
      Sample sam1=new Sample("父类 sam1成员初始化");
 static Sample staticSam2=new Sample("父类 静态成员staticSam2初始化");
 static{
            System.out.println("父类 static 块 2  执行");
            }
      Test()
      {
            System.out.println("父类 Test默认构造函数被调用");
      }
      Sample sam2=new Sample("父类 sam2成员初始化");
}
class TestSub extends Test
{
 static Sample staticSamSub=new Sample("子类 静态成员staticSamSub初始化");
      TestSub()
      {
            System.out.println("子类 TestSub 默认构造函数被调用");
      }
      Sample sam1=new Sample("子类 sam1成员初始化");
 static Sample staticSamSub1=new Sample("子类 静态成员staticSamSub1初始化");
 static{System.out.println("子类 static 块  执行");}
      Sample sam2=new Sample("子类 sam2成员初始化");
}

执行结果:

父类 static 块 1 执行

父类 静态成员staticSam1初始化

父类 静态成员staticSam2初始化

父类 static 块 2 执行

--------父类静态成员初始化

子类 静态成员staticSamSub初始化

子类 静态成员staticSamSub1初始化

子类 static 块 执行

-------子类静态成员初始化

父类 sam1成员初始化

父类 sam2成员初始化

父类 Test默认构造函数被调用

-------父类普通成员初始化和构造函数执行

子类 sam1成员初始化

子类 sam2成员初始化

子类 TestSub 默认构造函数被调用

-------父类普通成员初始化和构造函数执行

由此得出Java初始化顺序结论:

1 继承体系的所有静态成员初始化(先父类,后子类)

2 父类初始化完成(普通成员的初始化-->构造函数的调用)

3 子类初始化(普通成员-->构造函数)

Java初始化顺序如图:

有的朋友问到内部的机制,上述的初始化顺序是由下面的几条规则决定的:

1.首先初始化静态域是因为静态域是放在方法区和class对象在一起的。 2.由于类加载的时候,会向上查找基类,因为子类的初始化依赖于基类首先初始化。所以会首先发生“基类->子类"顺序的类加载,类加载过程中,顺便完成了静态域的初始化。 3.另外一条规则是初始化块和域的初始化按照声明的顺序进行。

详见thinking in java中译本第四版的P147页。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java达人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档