1 序言:
Java中子类、父类变量,代码块,以及构造方法的加载顺序,是我们在程序开发中经常遇到的一个问题,也是比较容易混淆的。
2 正文
为此,我们先来分析一下,一个java程序的构成:
变量: 成员变量(静态变量又叫类变量、实例变量)和局部变量
方法: 成员方法和构造方法
代码块:普通代码块、构造代码块、静态代码块、同步代码块
想要弄清楚子类、父类变量,代码块,以及构造方法的加载顺序,无非就是搞明白变量、方法和代码块的加载顺序。而java中的继承是继承父类的成员变量和成员方法,注意不包括构造方法;New一个对象的过程初始化对象的成员变量(属性),然后初始化对象的构造方法,子类构造方法中默认有super(),因此先父类构造方法后子类构造方法。
由以上分析可得,父类的静态成员变量—-父类静态代码块—-子类静态成员变量—-子类静态代码块—父类构造代码块—父类无参构造方法—子类构造代码块—子类构造方法。
2.1
例子
父类
`public class Person {
public static String name = "
皇帝
";
public String age="100";
public String sex="male";
//
无参构造方法
public Person() {
System.out.println("
父类的无参构造方法
"+sex);
drink();
}
//
有参构造方法
public Person(String a) {
System.out.println("
父类的有参构造方法
" + a);
}
//
构造代码块
{
System.out.println("
父类中的构造代码块
"+"==="+sex);
}
//
静态代码块
static {
//name = "
女娲
";
System.out.println("
父类静态代码块
" +"==="+ name);
}
//
public void drink() {
System.out.println("
我要喝水
");
};
}
子类
public class Man extends Person {
public static String name = "
秦始皇
";
public String age = "
长生不老
";
public String sex="female";
//
无参构造方法
public Man() {
System.out.println(sex);
drink();
System.out.println("
子类的无参构造方法
");
}
//
有参构造方法
public Man(String a) {
System.out.println("
子类的有参构造方法
" + a);
}
//
构造代码块
{
System.out.println("
子类构造代码块
"+"==="+sex);
}
//
静态代码块
static {
System.out.println("
子类静态代码块
"+"==="+name);
}
@Override
public void drink() {
System.out.println("
我要喝长生不老水
");
};
public static void main(String args[]) {
String a = "123";
new Man();
}
}
2.2 程序运行结果
父类静态代码块===皇帝
子类静态代码块===秦始皇
父类中的构造代码块===male
父类的无参构造方法male
我要喝长生不老水
子类构造代码块===female
female
我要喝长生不老水
子类的无参构造方法
总结:
通过以上分析和实例可以确定,执行顺序为
父类的静态成员变量—-父类静态代码块—-子类静态成员变量—-子类静态代码块—父类构造代码块—父类无参构造方法—子类构造代码块—子类构造方法。
但是你有没有发现漏了点什么呢?我们知道子类的成员变量优先于子类的构造方法执行,那么父类的成员变量是什么时候加载呢?今天先到这里了,明天好好说说jvm的运行过程。