Java 类成员的初始化顺序

前言:开发中碰到一个Java文件中有很多的成员变量,包括静态和非静态的,还有很多的初始化方法,很好奇这些成员的初始化顺序,在这里作个研究。

 

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初始化顺序为:

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

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

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

 

 

Java初始化顺序如图:

 

参考文献:

Java初始化顺序

Java 类成员的初始化顺序的更多相关文章

  1. Java中类成员变量初始化顺序

    一. 定义处默认初始化vs构造函数中初始化 java中类成员变量支持在声明处初始化,也可以在构造函数中初始化,那么这两者有什么区别呢?看下面例子 public class FieldsInit { p ...

  2. Java类的变量初始化顺序

    大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台 ...

  3. java类中元素初始化顺序

    结论:对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序依次是(静态变量.静态初始化块)>(变量.初始化块)>构造器. public class Test4 { @Tes ...

  4. java类及实例初始化顺序

    1.静态变量.静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只在类加载时,初始化一次) 2.非静态变量.非静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只要 ...

  5. java类对象的初始化顺序

    在下面这个例子中,我们分别在父类和子类中测试了静态代码块.普通代码块.静态成员变量.普通成员变量.构造器.静态内部类. 一:代码块及变量测试 class Field{ public static St ...

  6. c++ 类成员的初始化顺序

    class TestClass1 { public: TestClass1() { cout << "TestClass1()" << endl; } Te ...

  7. java类中元素初始化顺序详解

    父类静态变量父类静态块子类静态变量子类静态块父类普通变量父类普通块父类构造方法子类普通变量子类普通块子类构造方法

  8. java类中成员的初始化顺序(一)

    类被创建之后的成员的初始化顺序到底是怎么样的? 首先 不考虑继承 package com; public class DemoOne { /** * 关于类的初始化顺序 */ //不考虑继承结构的情况 ...

  9. java中的多构造函数以及类字段的初始化顺序

    1.同一个类可以有多个构造函数,多个构造函数之间通过参数来区分.这是方法重载的一个实例.构造函数之间可以相互调用. 2.类的初始化块:可以在类中使用“{”和“}”将语句包围起来,直接将其作为类的成员. ...

随机推荐

  1. 制作简易计算器处理结果Servlet

    ResultServlet.java: package com.you.servlet; import java.io.IOException; import java.io.PrintWriter; ...

  2. SQL SERVER中查找某关键词位于哪些存储过程或函数

    USE [MYDB] go SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_type='PROCEDURE' AND routine_d ...

  3. vm.dirty_ratio & vm.dirty_background_ratio

    https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/ Better Lin ...

  4. ecshop被加入了黑链

    朋友一个ecshop网站被攻击了,查看代码如下: <?php $password = "1";//设置密码 error_reporting(E_ERROR); header( ...

  5. 如何使用nodejs发邮件

    昨天就开始想使用nodemailer来实现一个发送邮件的功能,不过发现了很多个坑,网上给的资料也很杂很乱,所以决定写一篇真正能用的来帮助大家减少弯路 首先,我们先来看下代码,如上所示. 步骤: 1.下 ...

  6. 小白日记50:kali渗透测试之Web渗透-CSRF

    CSRF CSRF原理:经常与XSS混淆. 从信任的角度进行区分:XSS:利用用户对站点的信任:CSRF:利用站点对已经身份认证的信任(有一定的信任)[默认情况:站点不信任客户端] 结合社工在身份认证 ...

  7. find the nth digit

    Problem Description 假设:S1 = 1S2 = 12S3 = 123S4 = 1234.........S9 = 123456789S10 = 1234567891S11 = 12 ...

  8. Java中ThreadLocal的设计与使用

    早在Java 1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了一种新的选择.使用这个工具类可以很简洁地编写出优美的多线程程 ...

  9. CBM-业务组件模型

  10. jQery简单Tab选项卡效果

    简单的Tab效果 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...