关于Java的静态块、非静态块和静态方法

来源:互联网 发布:苹果数据线头焊接 编辑:程序博客网 时间:2024/06/03 19:49

一、代码块和构造函数的初始化顺序
先从实例代码开始
父类

public class SuperClass {    static {        System.out.println("super static block init");    }    {        System.out.println("no static block init");    }    public SuperClass() {        System.out.println("super Instance");    }

子类

 public class SubClass extends SuperClass {    static {        System.out.println("sub static block init");    }    {        System.out.println("sub no static block init");    }    public SubClass() {        System.out.println("sub Instance");    }}

下面这行代码的数据结果是什么?

SuperClass superClass = new SuperClass();

输出结果

super static block initno static block initsuper Instance

总结:针对单个类,初始化顺序:静态代码块,非静态代码块,构造函数


下面的这行代码又会输出怎么样的结果?

SubClass subClass = new SubClass();

输出结果

super static block initsub static block initno static block initsuper Instancesub no static block initsub Instance

子类实例化时,输出的顺序如下:
父类的静态代码块->子类的静态代码块->父类的非静态代码块->父类的构造函数->子类的非静态代码块->子类的构造函数


二、代用静态方法和静态变量
下面的示例代码分析

父类

public class SuperClass {    static {        System.out.println("super static block init");    }    {        System.out.println("no static block init");    }    public SuperClass() {        System.out.println("super Instance");    }    public static void superTest() {        System.out.println("super method");    }    public static final Integer countInteger = 123;    public static final int countInt = 345;}

子类

public class SubClass extends SuperClass {    static {        System.out.println("sub static block init");    }    {        System.out.println("sub no static block init");    }    public SubClass() {        System.out.println("sub Instance");    }    public static void sub() {        System.out.println("sub method");    }    public static final String hello = "hello";    public static final int testInt = 3;    public static final Integer testInteger = 4;}

观察输出结果:

System.out.println(SuperClass.countInt); //345********************System.out.println(SuperClass.countInteger);// super static block init// 123********************System.out.println(SubClass.countInteger);// super static block init// 123********************System.out.println(SubClass.countInt);// 345********************SuperClass.superTest();// super static block init// super method********************SubClass.superTest();// super static block init// super method********************System.out.println(SubClass.testInt);// 3********************System.out.println(SubClass.testInteger);// super static block init// sub static block init// 4********************System.out.println(SubClass.hello);// hello********************SubClass.sub();// super static block init// sub static block init// sub method********************SubClass[] subClasses = new SubClass[2];//无任何内容输出

总结

  1. 子类调用父类的静态字段或者静态方法,只会触发父类的初始化;
  2. 父类调用父类的静态方法,会触发父类的静态块初始化;
  3. 子类调用子类的静态方法,会触发父类的静态块和子类的静态块的初始化;
  4. 关于Int,string 和Integer输出结果的不同,是由于Int和string类型在编译阶段jvm放到了常量池中。

参考:https://segmentfault.com/a/1190000005916150

0 0