public class TestExtends {
public static void main(String[] args) {
Son son1 = new Son();
}
}
class Parent {
private static int a = 1;
static{//静态代码块
System.out.println("a = "+a);
}
private int b = 2;
{//动态代码块
System.out.println("b = "+b);
}
public Parent(){
System.out.println("---------parent----------");
}
}
class Son extends Parent{
private static int c = 1;
static{
System.out.println("c = "+c);
}
private int d = 2;
{
System.out.println("d = "+d);
}
public Son(){
//super();默认调用,当父类只有有参的构造器时就要显示调用有参构造器才行,如super(c);
System.out.println("---------------son-------------");
}
}
输出结果:
a = 1
c = 1
b = 2
---------parent----------
d = 2
---------------son-------------
对于java继承中的价载顺序其实一直不是很了解,最近看了<thinking in java>里面的解释,发现大体是理顺了,所以记录一下,方便以后查看:
1,加载的时候先是类加载:就是说一个类要new对象,是要先把类加载进jvm的,一旦他发现了extends关键字的话,就会先去加载父类的类文件,一层一层的父类加载完了之后,最后才是子类本身;
加载类文件的同时,类变量(static)先加载,所以上面的例子输出结果如下:(为了输出结果用到了静态跟动态代码块,其实就把这两块东西当做静态变量跟成员变量理解就可以了,他们的最大作用是起到
变量的初始化而已)
a = 1
c = 1
2,经过了类加载一步后,开始要来新建对象了,在子类的构造器中是会默认先调用父类的构造器的,所以父类先建对象,也就是先加载父类的成员变量,然后再执行父类的构造器里面的内容,得到结果如下:
b = 2
---------parent----------
3,父类的对象新建完成,轮到子类的了,子类开始初始化成员变量,然后执行本身的构造器里面的内容,得到结果如下:
d = 2
---------------son-------------
PS:对于<thinking in java>中有一句话,很是疑惑,中文版P94页里面写到“无法阻止自动初始化的进行,它将在构造器被调用之前发生。。。”,当初因为这个还以为是先加载成员变量,再执行构造器里面的super(),结果是super先执行了。。。是我理解有问题?