java t初始化_[Java] 类的初始化步骤

前言

类的初始化过程,可在多线程环境下进行的,为了简化,本文介绍的单线程情况下的类初始化步骤。

此外,继承情况下的顺序不是本文焦点,本文重点在于一个类的内部字段的初始化顺序。想了解继承情况下的初始化情况,可参看 类和接口的初始化步骤 - 继承方面

本文介绍的是类的初始化,不涉及实例的初始化。

正文

类的初始化,包括静态代码块的初始化、静态字段(类的字段)的初始化。

类的初始化触发条件:

1) T 是一个类,且 T 的一个实例被创建。

2) T 的一个静态方法被调用

3) T 的一个静态字段被赋值

4) T 的一个静态字段被使用,并且该字段不是一个字面常量。

5) T 是一级类,并且内嵌的断言语句被执行

本文的采用第 4) 种触发条件进行演示。

一个类的初始化步骤:

1. 在一个类被初始化之前,也就是在任何非字面类常量的类字段被初始化之前,字面类常量先完成初始化,如字段 static final Stirng a = "good"。

2. 当类被触发进行初始化,若其直接父类还没有被初始化,先对直接父类进行初始化;若直接父类的直接父类没有被初始化,则先对直接父类的直接父类进行初始化,以此类推,直到 Object 类或某一级别的祖父类已被初始化。

3. 初始化所有非类常量的类字段,同时初始化静态代码块,按文本序。

例子

Super, 父类,被初始化有输出

Test,测试主体类,继承 Super, 拥有四个字段:字面类常量 field1, 非字面的类常量 field2, 类变量 field3, 实例变量 field4; 拥有静态代码块,在类被初始化时被执行。

Test$InnerClass,Test 的内部类,在 Test 初始化时候被调用,用于表明字面类常量、非字面类常量两者被初始化的时间是不一样的。

InitDemo, 演示类的时候步骤。

具体代码

Super, 父类

public classSuper {static{

System.out.println("initializing Super ");

}

}

Test, 测试的主体类

public class Test extendsSuper {public static final String field1 = "Test.field1";public static final String field2 = InnerClass.pint("Initializing Test.field2 ");public static String field3 = InnerClass.pint("Initializing Test.field3 ");public String field4 = InnerClass.pint("Initializing Test.field4 ");static{

System.out.println("initializing Test class ");

System.out.println("\t" + field1 + " - " + field2 + " - " +field3);

}publicTest(){

System.out.println("in Test() ");

}public voidbMethod() {

System.out.println("in Test.bMethod() ");

}public static classInnerClass{public staticString pint(String s){

System.out.println(s);return s.substring(s.indexOf(" ") + 1);

}static{

System.out.println("initialzation in Test$innerClass ");

System.out.println("\t" + field1 + " - " + field2 + " - " +field3);

}

}

}

InitDemo, 演示 Test 被初始化的步骤

public class InitDemo {

public static void mian(){

System.out.println(Test.field1);

System.out.println("----------");

System.out.println(Test.field2);

}

}

输出如下

1 Test.field12 ----------

3 initializing Super4 initialzation inTest$innerClass5 Test.field1 - null - null

6 Initializing Test.field27 Initializing Test.field38 initializing Test class9 Test.field1 - Test.field2 -Test.field310 Test.field2

从输出可以看出 :

在输出字面类常量 Test.field1 时候, Test 类并没有被初始化。而在输出非字面的类常量 Test.field2 时候,触发了 Test 的初始化。

在 Test 类被初始化之前,其父类 Super 先被初始化。

第 5 行是内部类 Test$innerClass 的输出,Test 类被初始化之前,非字面类字段 filed2、field3 都为 null,只有字面类常量 field1 已被赋值。

地 9 行是 Test 类静态代码块的初始化运行,此时类字段 field2、field3 均已被初始化。

类的初始化只是对类字段 ( field1、field2、field3 ) 进行初始化赋值,实例字段 field4 并不会被初始化赋值,需要等到创建实例是才会被初始化创建。

参考资料

12.4. Initialization of Classes and Interfaces, The Java Language Specification, Java SE 8 Edition

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值