Java程序的执行顺序以及赋值顺序

来源:互联网 发布:java 如何实现方法重载 编辑:程序博客网 时间:2024/05/20 03:43

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=子类构造函数赋值。


也就是说其赋值顺序变成:
父类非静态代码块赋值 ->父类成员变量赋值 -> 父类构造函数赋值 -> 子类非静态代码块赋值 -> 子类成员变量赋值 -> 子类构造函数赋值

1 0