一道简单有趣的java题:输出顺序的问题

Java构造方法中的执行顺序

SEP 8TH, 2013 | COMMENTS

这道题来自 stackoverflow

问题描述:

有如下代码,求其输出内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test
{
    public int a = 10;
    Test(){System.out.println("1");}

    {System.out.println("2");}

    static{System.out.println("3");}

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

分析

作为静态区段的语句,容易知道,3 是会最先出现的。容易弄错的一点是 到底是 1 和 2 的出现顺序。

我们可以参考字节码来分析。在 eclipse 中使用 ASM bytecode 插件,得到相应的字节码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// class version 50.0 (50)  
// access flags 0x21  
public class Test {
  // compiled from: Test.java  
  static <clinit>() : void
    GETSTATIC System.out : PrintStream
    LDC "3"
    INVOKEVIRTUAL PrintStream.println(String) : void
    RETURN

  <init>() : void
    ALOAD 0: this
    INVOKESPECIAL Object.<init>() : void
    ALOAD 0: this
    BIPUSH 10
    PUTFIELD Test.a : int
    GETSTATIC System.out : PrintStream
    LDC "2"
    INVOKEVIRTUAL PrintStream.println(String) : void
    GETSTATIC System.out : PrintStream
    LDC "1"
    INVOKEVIRTUAL PrintStream.println(String) : void
    RETURN


  public static main(String[]) : void
    NEW Test
    INVOKESPECIAL Test.<init>() : void
    RETURN
}

正如我们所想,3 是被放在类构造方法中,这是类的初始化函数,固然在类的初始化时出现。

而在构造方法中先出现 2,之后才是 1。问题的核心集中到对象构造方法的指令顺序问题。实际上,在对象构造方法中,会先执行一些隐性的指令,比如父类的构造方法、{}区段的内容等,然后在执行显性的构造方法中的指令:

    1. Java 编译时,对象构造方法里先嵌入隐式的指令,完毕之后,再执行 Java 源代码中显示的代码。
  • 2.那些隐式的指令,包括父类的构造方法、变量的初始化、{}区段里的内容,并严格按照这个顺序嵌入到对象的构造方法中。


  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值