Java中成员变量、构造方法、代码块执行顺序剖析

今天,测试了一下java中成员变量、构造方法、代码块等的执行顺序,代码如下:

package com.carol.entity;

/**
 * @author Carol Tang
 * @version 1.0.0
 * @date 2018-09-13 10:37
 * @description 测试java中各代码的执行顺序
 **/
class G_Member{
    G_Member(){
        System.out.println("[初始化G_Member实例成员变量]");
    }
}

class G_StaticMember{
    G_StaticMember(){
        System.out.println("[初始化G_StaticMember静态成员变量]");
    }
}


class F_Member{
    F_Member(){
        System.out.println("[初始化F_Member实例成员变量]");
    }
}
class F_StaticMember{
    F_StaticMember(){
        System.out.println("[初始化F_StaticMember静态成员变量]");
    }
}

class Grantfather {
    //静态成员变量g_staticMember
    static G_StaticMember g_staticMember = new G_StaticMember();
    //实例成员变量g_member
    G_Member g_member = new G_Member();
    //静态成员变量name
    public static String name = "grantfather";
    //实例成员变量age
    public int age = 18;

    static {
        System.out.println("Grantfather类,static静态代码块");
    }

    {
        System.out.println("Grantfather类,构造代码块");
    }
    Grantfather() {

        System.out.println("Grantfather类,无参构造方法,name = "+ name);
    }

    Grantfather(String name){
        this.name = name; //如果没有将传入的参数赋值给本类的name,则默认输出是传入的参数值,而非本类静态name值
        System.out.println("Grantfather类,有参构造方法,name = "+name);
    }

    Grantfather(int age){
        System.out.println("Grantfather类,有参构造方法,age = "+age);//默认输出是传入的参数值,而非本类age
    }
}
class Father extends Grantfather{
    public String name = "father";
    //静态成员变量 f_staticMember
    static F_StaticMember f_staticMember = new F_StaticMember();
    //实例成员变量f_member
    F_Member f_member = new F_Member();

    static {
        System.out.println("Father类,static静态代码块");
    }

    {
        System.out.println("Father类,构造代码块");
    }
    Father(){
//        super();
//        super.name = "txx";
        super("txx");
        //super(20);
        System.out.println("Father类,无参构造方法,name = "+name);
    }
    Father(int age){
        super();
        super.age = age;//此处将修改Grantfather类的age,则Father类的age也改变
        System.out.println("Father类,有参构造方法,name = "+name);
        System.out.println("Father类,有参构造方法,age = "+age);
    }
}
class Son extends Father{
    Son(){
        super();
        System.out.println("Son类,无参构造方法");
        System.out.println("Son类,name = "+name);
        System.out.println("Son类,age = "+age);
    }
}

public class Test{
    public static void main(String[] args){
        System.out.println("=======================第 1 次开始执行==================================");
        Grantfather grantfather = new Grantfather();

        System.out.println("=======================第 2 次开始执行==================================");
        Grantfather grantfather2 = new Grantfather();

        System.out.println("=======================第 3 次开始执行==================================");
        Grantfather grantfather3 = new Grantfather("carol");

        System.out.println("=======================第 4 次开始执行==================================");
        Grantfather grantfather4 = new Grantfather(20);
        System.out.println("Grantfather类,age = "+grantfather4.age);
        System.out.println("Grantfather类,name = "+grantfather4.name);

        System.out.println("=======================第 5 次开始执行==================================");
        Father father = new Father();

        System.out.println("=======================第 6 次开始执行==================================");
        Father father2 = new Father(99);
        System.out.println("Father类,age = "+father2.age);

        System.out.println("=======================第 7 次开始执行==================================");
        Son son = new Son();

        System.out.println("========================第 8 次开始执行=================================");
        Grantfather grantfather5 = new Grantfather();
        System.out.println("Grantfather类,name = "+grantfather5.name);
    }
}

输出结果如下:

=======================第 1 次开始执行==================================
[初始化G_StaticMember静态成员变量]
Grantfather类,static静态代码块
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = grantfather
=======================第 2 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = grantfather
=======================第 3 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,name = carol
=======================第 4 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,age = 20
Grantfather类,age = 18
Grantfather类,name = carol
=======================第 5 次开始执行==================================
[初始化F_StaticMember静态成员变量]
Father类,static静态代码块
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,name = txx
[初始化F_Member实例成员变量]
Father类,构造代码块
Father类,无参构造方法,name = father
=======================第 6 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = txx
[初始化F_Member实例成员变量]
Father类,构造代码块
Father类,有参构造方法,name = father
Father类,有参构造方法,age = 99
Father类,age = 99
=======================第 7 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,name = txx
[初始化F_Member实例成员变量]
Father类,构造代码块
Father类,无参构造方法,name = father
Son类,无参构造方法
Son类,name = father
Son类,age = 18
Son类,name = father
Son类,age = 18
========================第 8 次开始执行=================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = txx
Grantfather类,name = txx

说明: 
    一般的类里面包含: 
    1、静态代码块(静态区、静态变量等) 
    2、构造代码块({ }中间的内容)
    3、成员变量(静态成员变量、实例成员变量) 
    4、构造方法(有参构造方法、无参构造方法)

总结:
     一般类中代码执行顺序如下:(“>” 表示优先于)

  •          静态成员变量 > 实例成员变量 > 构造代码块 > 构造方法 ;
  •          静态代码块 > 构造代码块 > 构造方法;
  •          静态成员变量和静态代码块在类初始化阶段被初始化,且只初始化一次,两者顺序按照代码从上到下执行;

         需要注意的是:
             静态成员变量由于只被初始化一次,后续一旦被修改的,再实例化对象时,静态成员变量的值会是修改后的值,因此要慎用!
             一般一次定义后永不再修改的变量,可声明为静态成员变量。
     考虑到继承的特性,子类与父类的执行顺序是:

  •         静态代码块(父) > 静态代码块(子) > 实例成员变量(父) > 构造代码块(父) > 构造方法(父) > 实例成员变量(子) > 构造代码块(子) > 构造方法(子)

         扩展:
             在子类中使用super(),默认调用的是父类的无参构造函数;
             使用有参构造方法时,需注意如果方法里没有如:this.age = age ,则此类的成员变量age的值将不会被改变。

参考链接:https://baijiahao.baidu.com/s?id=1588663308864677376&wfr=spider&for=pc

猜你喜欢

转载自blog.csdn.net/flyer_tang/article/details/82686692