一道关于类加载机制的面试题

class A {
static {
System.out.print("1");
}
public A() {
System.out.print("2");
}
}
 
 
class B extends A{
static {
System.out.print("a");
}
public B() {
System.out.print("b");
}
}
 
 
 
public class Hello {
public static void main(String[] args) {
A ab = new B();
ab = new B();
}
}
 
执行结果:1a2b2b。
 
解析:

当执行A ab = new B()时候,由于JVM事先就会知道B是继承至A的,所以需要先加载A,如果不先加载A的话,无法完成子类B的加载!所以类的加载顺序和构造器执行顺序一致,先父类再子类!

注意:容易糊涂的地方是,以为B ab =new B();以为创建B所以先加载B之后再加载A,这种理解就错误了,因为对于对象的创建是从父类开始的!

拓展:

创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。

非静态代码块的执行顺序也是先父类,在子类!但是非静态代码块执行顺序在静态代码块之后,构造器之前!静态代码块只会执行一次(类加载时候执行),而非静态代码块会多在创建对象时候多次执行!

原文地址:https://www.cnblogs.com/shuai666/p/14467621.html