在JAVA虚拟机中,对于类和接口的加载有不同的处理方式。
问题1???
继承过程中的加载情况。
在【JVM虚拟机】类的加载,连接和初始化 这篇文章中提到了Java对类的主动使用有7种,其中有一种是初始化一个类的子类
,对于这样的情况,我们先写一个案例看看
public class Test5 {
public static void main(String[] args) {
System.out.println(MyChild5.num1);
}
}
class MyParent5 {
static {
System.out.println("MyParent5 invoked");
}
}
class MyChild5 extends MyParent5 {
public static int num1 = 1;
static {
System.out.println("MyChild5 invoked");
}
}
运行结果
MyParent5 invoked
MyChild5 invoked
1
发现,会先执行父类的类,然后执行子类的。
那对于类是这样的,那接口呢???
相信这里联想到上一章关于【JVM虚拟机】类的加载之常量池 的内容和接口中属性的特性,也能联想到会不会加载父类。 我们先写个例子看看
/**
* 接口的加载
*/
public class Test4 {
public static void main(String[] args) {
System.out.println(MyChild4.num2);
}
}
interface MyParent4{
public static final Thread thread = new Thread(){
//这个解释下: 我们之前一直使用的是static{} 静态代码块,
//{} 则是实例代码块,当被实例化后,则会执行的。优先于构造函数
{
System.out.println("MyParent4 invoke");
}
};
}
interface MyChild4 extends MyParent4{
public static final int num2 = 2;
}
运行结果看看
2
说明在调用子接口的时候并没有去加载父接口。
结论:在接口继承关系中,调用子接口的属性,并不会去加载父接口。
问题2???
关于类在继承下的加载过程
public class Test6 {
public static void main(String[] args) {
System.out.println(MyChild6.num1);
}
}
class MyParent6 {
public static int num1 = 1;
static {
System.out.println("MyParent6 invoked");
}
}
class MyChild6 extends MyParent6 {
public static int num2 = 3;
static {
System.out.println("MyChild6 invoked");
}
}
输出结果
MyParent6 invoked
1
结论:在调用子类继承父类的静态属性后,并不会去加载子类。