java - 实例变量的执行顺序

标签 java

我知道类中的静态和初始化 block 及其执行顺序。但是下面的代码引起了一些疑问。

class Test1 {
   Test1(int x) {
      System.out.println("Constructor value : " + x);
   }
}

public class Test2 {
   Test1 t1 = new Test1(10);    ----- line 8
   Test2(int i) {
       t1 = new Test1(i);
   } 

  public static void main(String[] args) {
     Test2 t2 = new Test2(5);
  }
}

此代码的输出:
构造函数值:10
构造函数值:5


我的问题是实例变量(第 8 行)在创建类(Test2)的对象或发生其他一些事情后立即执行。

最佳答案

初始化程序和初始化 block 的执行就像它们被插入到每个构造函数的顶部(在基类中)或在调用 super(...) 之后一样。 (在一个子类中)。¹所以你的 Test2在功能上等同于:

public class Test2 {
   Test1 t1;
   Test2(int i) {
       t1 = new Test1(10);
       t1 = new Test1(i);
   } 

  public static void main(String[] args) {
     Test2 t2 = new Test2(5);
  }
}

¹事实上,如果您查看字节码,这确实是真的......

例如,假设我们向 Test2 添加第二个构造函数。 :
public class Test2 {
    Test1 t1 = new Test1(10);

    Test2(int i) {
        t1 = new Test1(i);
    } 

    Test2(int i, String s) {
        t1 = new Test1(i);
    } 

    public static void main(String[] args) {
        Test2 t2 = new Test2(5);
    }
}

然后编译它,并使用 javap -c Test2查看字节码(大致):

编译自“Test2.java”
公共(public)类Test2 {
测试1 t1;

测试2(int);
代码:
0:aload_0
1: invokespecial #1//方法 java/lang/Object."":()V
4:aload_0
5: new #2//类 Test1
8:重复
9:双推 10
11: invokespecial #3//方法 Test1."":(I)V
14: putfield #4//字段 t1:LTest1;

17:加载_0
18: new #2//类 Test1
21:重复
22:iload_1
23: invokespecial #3//方法 Test1."":(I)V
26: putfield #4//字段 t1:LTest1;
29:返回

Test2(int, java.lang.String);
代码:
0:aload_0
1: invokespecial #1//方法 java/lang/Object."":()V
4:aload_0
5: new #2//类 Test1
8:重复
9:双推 10
11: invokespecial #3//方法 Test1."":(I)V
14: putfield #4//字段 t1:LTest1;

17:加载_0
18: new #2//类 Test1
21:重复
22:iload_1
23: invokespecial #3//方法 Test1."":(I)V
26: putfield #4//字段 t1:LTest1;
29:返回

公共(public)静态无效主(java.lang.String[]);
代码:
0: new #5//类 Test2
3:重复
4:iconst_5
5: invokespecial #6//方法 "":(I)V
8:astore_1
9:返回
}

你可以看到t1 = new Test1(10)在两个构造函数中。

关于java - 实例变量的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60018407/

相关文章:

java - java中的固定格式数字。 (如何剪号?)

java - 跨越多个存储库的 Spring Data Transaction

java - Scala 中 Java 8 Supplier 接口(interface)的等价物

Java 客户端连接错误 : ChangeCipherSpec message sequence violation

java - 如何将使用 MPAndroidChart 库绘制的饼图中的图例居中?

java - Derby Eclipse 类路径

java - 集合<字符串>

java - 我会只使用 do while 循环吗?

java - 冒泡排序模块似乎不起作用;输出错误列表(java)

java - 估计 BigDecimal 计算时间