java类里的初始化顺序
主要演示一下java类里面各个部分的初始化顺序以及不触发初始化的一些情况
我直接用例子说明一下
示例代码(不带继承的情况):
public class TestInit {
public static String staticField = "静态变量";
public String normalField = "变量";
static
{
System.out.println( staticField + "静态初始化块" );
}
{
System.out.println( normalField + "初始化块");
}
public InitialOrderTest()
{
System.out.println( "构造器" );
}
public static void main( String[] args )
{
new TestInit();
}
}
输出:
1.静态变量
2.静态初始化块
3.变量
4.初始化块
5.构造器
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序是静态变量>静态初始化块>变量>初始化块>构造器
示例代码(带有继承情况):
public class A {
public static String parentStaticField = "父类静态变量";
public String parentField = "父类变量";
static
{
System.out.println( parentStaticField );
System.out.println( "父类静态初始化块" );
}
{
System.out.println( parentField );
System.out.println( "父类初始化块" );
}
public A()
{
System.out.println( "父类构造器" );
}
}
public class B extends A {
public static String sonStaticField = "子类静态变量";
public String sonField = "子类变量";
static
{
System.out.println( sonStaticField );
System.out.println( "子类静态初始化块" );
}
{
System.out.println( sonField );
System.out.println( "子类初始化块" );
}
public B()
{
System.out.println( "子类构造器" );
}
public static void main(String[] args) {
System.out.println("Main方法");
new B();
}
}
输出:
1.父类静态变量
2.父类静态初始化块
3.子类静态变量
4.子类静态初始化块
5.Main方法
6.父类变量
7.父类初始化块
8.父类构造器
9.子类变量
10.子类初始化块
11.子类构造器
子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。静态变量、静态初始化块,变量、初始化块初始化了顺序取决于它们在类中出现的先后顺序。
示例代码(不触发初始化):
class Super {
public static int parentStaticField = 111;
static
{
System.out.println(parentStaticField);
System.out.println("父类静态初始化块");
}
}
class son extends Super {
public static int sonStaticField = 111;
static
{
System.out.println(sonStaticField);
System.out.println("子类静态初始化快");
}
}
public class NonInit {
public static void main(String[] args) {
Super[] test = new Super[10];
}
}
输出:
由此可以看出,通过数组定义来引用类,不会触发此类的初始化(仅仅只是引用)
示例代码(不触发初始化):
public class finalInit {
public static void main(String[] args){
System.out.println(FinalFieldClass.finalField);
}
}
class FinalFieldClass {
public static String staticField = "静态变量";
static
{
System.out.println(staticField);
System.out.println("静态初始化块");
}
public static final String finalField = "Final变量";
}
输出:
1.Final变量
这里没有初始化FinalFieldClass类,是因为在编译的时候,常量(static final 修饰的)会存入调用类的常量池(此处是main函数所在的类的常量池),调用的时候本质上没有引用到定义常量的类,而是直接访问了自己的常量池,所以不会触发类的初始化