Java:类文件程序执行顺序

只要按照这个步骤,遇到这一类问题就可以解决了。

1. 类中所有属性的默认值(一举而成)

2. 父类静态属性初始化,静态块,静态方法的声明(按出现顺序执行)

3. 子类静态属性初始化,静态块,静态方法的声明 (按出现顺序执行)

4. 调用父类的构造方法,

首先父类的非静态成员初始化,构造块,普通方法的声明(按出现顺序执行)

然后父类构造方法

5. 调用子类的构造方法,

首先子类的非静态成员初始化,构造块,普通方法的声明(按出现顺序执行)

然后子类构造方法
      
说明: 1-3:类加载过程,不涉及构造方法

1-5: 实例化过程,涉及构造方法

参考问题:执行下列代码,输出是什么?

class A {
    public A() {
        System.out.println("A的构造方法");
    }

    public static int j = print();

    public static int print() {
        System.out.println("A print");
        return 521;
    }
}

public class Test1 extends A {
    public Test1() {
        System.out.println("Test1的构造方法");
    }

    public static int k = print();

    public static int print() {
        System.out.println("Test print");
        return 522;
    }

    public static void main(String[] args) {
        System.out.println("main start");
        Test1 t1 = new Test1();
    }
}

看看是不是这个?如果是那么执行顺序掌握的不错。

A print
Test print
main start
A的构造方法
Test1的构造方法

再来个上题加强版:问输出顺序是什么?

public class Test1 extends A {
    public Test1() {
        System.out.println("Test1的构造方法");
    }

    public static int k = print();

    {
      System.out.println(k);
    }
    
    public static int print() {
        System.out.println("Test print");
        return 522;
    }

    public static void main(String[] args) {
        System.out.println("main start");
        Test1 t1 = new Test1();
        Test1 t3;
        Test1 t2 = new Test1();
    }
}

class A {
    public A() {
        System.out.println("A的构造方法");
    }

    {
      System.out.println(j);
    }

    public static int j = print();

    static {
      System.out.println(j);
    }

    public static int print() {
        System.out.println("A print");
        return 521;
    }
    static{
      System.out.println("A的static block");
    }

}

看看输出是不是:

A print
521
A的static block
Test print
main start
521
A的构造方法
522
Test1的构造方法
521
A的构造方法
522
Test1的构造方法

重复输出的部分:

521
A的构造方法
522
Test1的构造方法

来自于第二次new过程中:运行父类构造体与构造方法->子类构造体与构造方法
而且也可以看出 类的申明不会调用类的构造体

上文转载自:https://www.cnblogs.com/greatfish/p/5771548.html

更新:
又看到一道类加载顺序题:https://blog.csdn.net/a352193394/article/details/7341015
这里修改成加强版,试试做不做得对。

问下面Test1运行输出什么?

public class Test1 {

 static Singleton singleton = new Singleton();

 public static void main(String[] args) {
   Singleton s = singleton.getSingleton();
   System.out.println("counter1 = "+s.counter1);
   System.out.println("counter2 = "+s.counter2);
 }
}


class Singleton{

 private static Singleton singleton = new Singleton();
 static {
   System.out.println(singleton.counter1);
   System.out.println(singleton.counter2);
 }
 public static int counter1;

 public static int counter2 = 3;

 public Singleton(){
   counter1++;
   counter2++;
 }

 public static Singleton getSingleton(){
   return singleton;
 }
}

说明:入口在Test1,Test1直接父类是java.lang.Object,那么开始模拟运行过程

先加载Test1父类Object,然后是Test1:

  1. Test1 成员赋予默认值:

    static singleton = null;

  2. Test1 静态成员初始化

    static Test1.singleton = new Singleton();调用了构造方法:
    这一步内部执行顺序:

    1)先加载组合内部成员Singleton类:
    成员赋予默认值,static Singleton.singleton =null,static Singleton.counter1 = 0,static Singleton.count2 = 0
    初始化静态成员singleton,运行构造函数,static Singleton.counter1 = 1,static Singleton.counter2 = 1
    执行static代码块:打印counter1的值1,换行,打印counter2的值1,换行
    初始化静态类成员Singleton.counter2 = 3;
    到此加载完毕,控制台已经输出1和1;此时static Singleton.counter1 = 1;static Singleton.counter 2 = 3

    2)初始化组合成员类对象 static singleton = new Singleton()
    这一步,调用构造方法后,static Singleton.counter 1 = 2,static Singleton.counter2 = 4
    到此Test1静态成员初始化完毕,static Singleton.counter 1 = 2,static Singleton.counter2 = 4

然后运行Main

  1. 执行Main函数
    1)Singleton s = singleton.getSingleton();
    s指向自己的静态成员类的静态成员类singleton.singleton,后者指向2-1)中的Singleton实例(此时带有静态变量counter1=2,counter2=4)
    2)打印counter1 = 2,换行
    3)打印counter2 = 4,换行

运行验证与模拟结果一样:

1
1
counter1 = 2
counter2 = 4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值