Java—类的实例化顺序

Java—类的实例化顺序

无继承关系时

1.静态成员变量->静态代码块->构造块->构造方法->普通变量初始化是在构造方法的第一条语句,如果有this()那么初始化在this()后

class Person{
    private int a=10;
    public Person() {
        //private int a=10; 初始化的地方
        System.out.println(a);
    }
    public Person(int a){
        this();
         //private int a=10;初始化的地方 
        this.a=a;
        System.out.println(this.a);
    }
}
public class Test {
    public static void main(String[] args) {
        new Person();
        new Person(5);
    }
}

程序运行结果是:
10
10
5

有继承关系时

1.父类的静态成员变量,父类的静态块(只进行一次,在类加载时)

2.子类的静态成员变量,子类的静态块(只进行一次)

3.父类的构造块->构造方法->普通成员变量(几次new就初始化几次)

4.子类构造块->构造方法->普通成员变量(几次new就初始化几次)

静态成员变量初始化位置:

class A{
    static{
        System.out.println("A的静态块");
    }
    {
        System.out.println("A的构造块");
    }
    public A(){
        System.out.println("A构造方法");
    }
}
class B{
    static A a1=new A();
    static{
        System.out.println("B静态块");
    }
    {
        System.out.println("B构造块");
    }
    public B(){
        System.out.println("B的构造方法");
    }
}
class Test extends B{
    static B b1=new B();
    static B b2=new B();

    static{
        System.out.println("Test静态块");
    }
    {
        System.out.println("Test构造块");
    }
    public Test(){
        System.out.println("Test的构造方法");
    }

    public static void main(String[] args) {
        new B();
        
    }
}

Java—类的实例化顺序

我们来分析上面程序,

1.由于Test类的成员变量用 static修饰,在类加载的时候初始化,进入父类B

2.由于B类 的成员变量用static修饰,在类加载时初始化,进入类A;

3.A 里运行顺序是 静态块->构造块->构造方法,然后回到B;

4.B里运行顺序是 静态块->构造块->构造方法,然后回到Test;

5.初始化第二个成员变量,进入B;

6.由于B的静态成员变量和静态块已经被初始化过了,所以不进入A 运行顺序为 >构造块->构造方法,返回Test;

7.执行Test的静态块,进入主方法, new B(),运行顺序 B 的构造块->构造方法

普通成员变量初始化位置:

abstract  class A{
    public A(){
        this.print();
    }
    abstract  public void print();
}

class B extends  A{
    private int n=100;
    public B(int n){
        super();
        this.n=n;
    }
    public void print(){
        System.out.println(this.n);
    }
}
public class Test {
    public static void main(String[] args) {
        new B(30);
    }
}

程序运行结果

0

分析:

1.new B(30),执行B的构造方法,但由于B是A 的子类,super()运行父类构造方法;

2.在父类里调用print(),方法,但是由于是实例化的是B,所以,引用的是B的print(),

3.输出B的普通成员变量,这时还没有初始化 所以值为0;

4.会到B的构造方法,然后初始化n为100;

5.然后给你赋值为30;结束