-
class A { -
static { -
System.out.print("a");//只有在类加载时候会执行一次 -
} -
public A() { -
System.out.print("x"); -
} -
} -
class B extends A { -
static { -
System.out.print("b"); -
} -
public B() { -
System.out.print("y"); -
} -
} -
public class Test { -
public static void main(String[] args) { -
A ab = new B(); -
System.out.println(); -
ab = new B(); -
} -
}
输出:abxy xy
执行过程:
A ab = new B();
执行时候第一使用到A、B类,JVM发现没有加载A、B的信息,故先加载,由于B继承了A类,所以会先加载A再加载B,在加载的过程中会执行static块完成类的初始化。所以会先输出ab,此时创建B对象时候,会先执行A的构造方法在执行B的构造方法,故在输出xy,所以最后输出abxy
当执行:
ab = new B();
时候发现已经加载过A、B的字节码了,故不会再加载了,所以不会输出ab,直接输出xy即可
如果代码修改为:
-
class A { -
static { -
System.out.print("a");// 只有在类加载时候会执行一次 -
} -
public A() { -
System.out.print("x"); -
} -
} -
class B extends A { -
static { -
System.out.print("b"); -
} -
public B() { -
System.out.print("y"); -
} -
} -
public class Test { -
public static void main(String[] args) { -
B ab = new B(); // 由于A ab = new B()=> B ab = new B() -
System.out.println(); -
ab = new B(); -
} -
}
输出还是:
abxy
xy
当执行B ab = new B()时候,由于JVM事先就会知道B是继承至A的,所以需要先加载A,如果不先加载A的话,无法完成子类B的加载!所以类的加载顺序和构造器执行顺序一致,先父类再子类!
注意:容易糊涂的地方是,以为B ab =new B();以为创建B所以先加载B之后再加载A,这种理解就错误了,因为对于对象的创建是从父类开始的!
拓展:非静态代码块的执行顺序也是先父类,在子类!但是非静态代码块执行顺序在静态代码块之后,构造器之前!静态代码块只会执行一次(类加载时候执行),而非静态代码块会多在创建对象时候多次执行!
实践代码:
-
class A { -
static { -
System.out.print("a");// 只有在类加载时候会执行一次 -
} -
{ -
System.out.print("a-a"); -
} -
public A() { -
System.out.print("x"); -
} -
} -
class B extends A { -
static { -
System.out.print("b"); -
} -
{ -
System.out.print("b-b"); -
} -
public B() { -
System.out.print("y"); -
} -
} -
public class Test { -
public static void main(String[] args) { -
B ab = new B(); // 由于A ab = new B()=> B ab = new B() -
System.out.println(); -
ab = new B(); -
} -
}
输出:
aba-axb-by
a-axb-by
如果两个类没有继承关系的话,类的加载顺序就是按照代码的执行顺序进行加载的。
-
class C { -
static { -
System.out.print("c"); -
} -
public C() { -
System.out.print("x"); -
} -
} -
class D { -
static { -
System.out.print("d"); -
} -
public D() { -
System.out.print("y"); -
} -
} -
public class Test1 { -
public static void main(String[] args) { -
C c=new C(); -
System.out.println(); -
D d=new D(); -
} -
}
输出:
cx
dy