顺序以下java
①父类静态变量和静态代码块(按照声明顺序);shell
②子类静态变量和静态代码块(按照声明顺序);数组
③父类成员变量和代码块(按照声明顺序);code
④父类构造器;对象
⑤子类成员变量和代码块(按照声明顺序);源码
⑥子类构造器。虚拟机
如下源码来自牛客中的一道题it
class A { public A() { System.out.println("class A"); } { System.out.println("I'm A class"); } static { System.out.println("class A static"); } } public class B extends A { public B() { System.out.println("class B"); } { System.out.println("I'm B class"); } static { System.out.println("class B static"); } public static void main(String[] args) { new B(); } }
运行结果io
class A static class B static I'm A class class A I'm B class class B
在分析上,若是父类即将调用的方法被子类重写了,那么父类就会调用子类重写后的方法,而不会调用父类的方法。编译
所以牢记,子类重写父类方法后,调用时会调用子类重写后的方法。
如下源码来自牛客中的一道题
public class Base { private String baseName = "base"; public Base() { callName(); } public void callName() { System.out.println(baseName); } static class Sub extends Base { private String baseName = "sub"; public void callName() { System.out.println(baseName); } } public static void main(String[] args) { Base b = new Sub(); } }
运行结果
null
子类实现的方法中调用的baseName为子类中的私有属性。
如下源码来自牛客中的一道题
public class Demo { class Super { int flag = 1; Super() { test(); } void test() { System.out.println("Super.test() flag=" + flag); } } class Sub extends Super { Sub(int i) { flag = i; System.out.println("Sub.Sub()flag=" + flag); } void test() { System.out.println("Sub.test()flag=" + flag); } } public static void main(String[] args) { new Demo().new Sub(5); } }
运行结果
Sub.test()flag=1 Sub.Sub()flag=5
JVM规范严格规定了有且只有5种状况必须对类进行“初始化”
java.lang.reflect
对类进行反射调用的时候,若类未初始化,则须要先触发其初始化被动引用:除了以上五种以外,其余的全部引用类的方式都不会触发初始化。
如下为被动引用的状况
/** * @author mmengyiyu */ public class NoInitialization { public static void main(String[] args) { System.out.println(SubClass.baseStaticIntVar); } } class Base { static final int baseStaticIntVar = 1; static { System.out.println("Base类的静态初始化块..."); } } class SubClass extends Base { static { System.out.println("SubClass类的静态初始化块..."); } }
运行结果
1
/** * @author mmengyiyu */ public class NoInitialization { public static void main(String[] args) { Base[] bases = new Base[5]; SubClass[] subClasses = new SubClass[5]; } } class Base { static { System.out.println("Base类的静态初始化块..."); } } class SubClass extends Base { static { System.out.println("SubClass类的静态初始化块..."); } }
无运行结果
不会触发类的初始化,天然不可能调用static代码块。
/** * @author mmengyiyu */ public class NoInitialization { public static void main(String[] args) { System.out.println(A.constantIntVar); } } class A { static { System.out.println("静态初始化块..."); } static final int constantIntVar = 100; }
运行结果
100