Java程序的执行顺序以及赋值顺序
关于Java程序父类及子类的静态代码块,非静态代码块以及构造函数的执行顺序,现构建Person类,Student类,测试类来讲解。
首先是Person类
public class Person {
private String name;
private int age;
private int sex;
private String str="父类成员变量赋值";
static{
System.out.println("执行Person的静态代码区。");
}
{
System.out.println("----进入父类非静态代码区----");
System.out.println("赋值前...");
System.out.println("str="+this.str);
System.out.println("赋值后...");
this.str="Person非静态代码区赋值。";
System.out.println("str="+this.str);
System.out.println("----退出父类非静态代码区----");
}
public Person(){
}
public Person(String name,int age,int sex){
System.out.println("----进入父类构造函数----");
System.out.println("赋值前...");
System.out.println("str="+this.str);
this.name=name;
this.age=age;
this.sex=sex;
this.str="父类构造函数赋值";
System.out.println("赋值后...");
System.out.println("str="+this.str);
System.out.println("----退出父类构造函数----");
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
然后是Student类
public class Student extends Person{
private int grade;
private String str="子类成员变量赋值";
static{
System.out.println("执行Student的静态代码区。");
}
{
System.out.println("----进入子类非静态代码区----");
System.out.println("赋值前...");
System.out.println("str="+this.str);
System.out.println("赋值后...");
this.str="Student非静态代码区赋值。";
System.out.println("str="+this.str);
System.out.println("----退出子类非静态代码区----");
}
public Student(){
}
public Student(int grade){
this.grade=grade;
}
public Student(String name,int age,int sex,int grade){
super(name,age,sex);
System.out.println("----进入子类构造函数----");
System.out.println("赋值前...");
System.out.println("str="+this.str);
this.grade=grade;
this.str="子类构造函数赋值。";
System.out.println("赋值前...");
System.out.println("str="+this.str);
}
public void print(){
System.out.println("I'm a Student.");
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
最后执行出来的结果是:
执行Person的静态代码区。
执行Student的静态代码区。
—-进入父类非静态代码区—-
赋值前…
str=父类成员变量赋值
赋值后…
str=Person非静态代码区赋值。
—-退出父类非静态代码区—-
—-进入父类构造函数—-
赋值前…
str=Person非静态代码区赋值。
赋值后…
str=父类构造函数赋值
—-退出父类构造函数—-
—-进入子类非静态代码区—-
赋值前…
str=子类成员变量赋值
赋值后…
str=Student非静态代码区赋值。
—-退出子类非静态代码区—-
—-进入子类构造函数—-
赋值前…
str=Student非静态代码区赋值。
赋值前…
str=子类构造函数赋值。
由此可见,Java程序代码的执行顺序为:
父类静态代码块 -> 子类静态代码块 -> 父类非静态代码块 ->父类构造函数 -> 子类非静态块 -子类构造函数
Java程序内赋值顺序为
父类成员变量赋值 -> 父类非静态代码块赋值 -> 父类构造函数赋值 -> 子类成员变量赋值 -> 子类非静态代码块赋值 -> 子类构造函数赋值
但是倘若把成员变量的初始化语句放在静态代码块后面:
Person类
{
System.out.println("----进入父类非静态代码区----");
System.out.println("赋值前...");
System.out.println("str="+this.str);
System.out.println("赋值后...");
this.str="Person非静态代码区赋值。";
System.out.println("str="+this.str);
System.out.println("----退出父类非静态代码区----");
}
private String str="父类成员变量赋值";
Student类
{
System.out.println("----进入子类非静态代码区----");
System.out.println("赋值前...");
System.out.println("str="+this.str);
System.out.println("赋值后...");
this.str="Student非静态代码区赋值。";
System.out.println("str="+this.str);
System.out.println("----退出子类非静态代码区----");
}
private String str="子类成员变量赋值";
其执行出来的结果为:
执行Person的静态代码区。
执行Student的静态代码区。
—-进入父类非静态代码区—-
赋值前…
str=null
赋值后…
str=Person非静态代码区赋值。
—-退出父类非静态代码区—-
—-进入父类构造函数—-
赋值前…
str=父类成员变量赋值
赋值后…
str=父类构造函数赋值
—-退出父类构造函数—-
—-进入子类非静态代码区—-
赋值前…
str=null
赋值后…
str=Student非静态代码区赋值。
—-退出子类非静态代码区—-
—-进入子类构造函数—-
赋值前…
str=子类成员变量赋值
赋值前…
str=子类构造函数赋值。
也就是说其赋值顺序变成:
父类非静态代码块赋值 ->父类成员变量赋值 -> 父类构造函数赋值 -> 子类非静态代码块赋值 -> 子类成员变量赋值 -> 子类构造函数赋值