繁体   English   中英

Java实例变量内部和外部构造函数的初始化混乱

[英]Java instance variable initialization inside and outside constructor confusion

让我们看一小段Java代码

class Foo {
  int i = 0;
  int j;
  public Foo(int j){
     this.j = j;
  }
}

上面的示例显示了Java中初始化变量的两种方法。 但是我的问题是哪个变量首先被初始化? 构造函数外部的变量还是构造函数内部的变量? 当我实例化上面的类Foo foo = new Foo(5) ,我知道该类的构造函数被调用,这意味着变量j首先被初始化。 谁能让我清楚订购的信息。

优先顺序

在您的情况下, int j首先发生并且默认为0 ,然后在构造函数被调用以创建新实例时重新分配为5

j仅在构造函数运行时重新分配。 当您在构造函数之外分配实例成员时,实例成员首先被初始化。

执行命令

每行代码都按其显示顺序执行。 声明总是按照代码中列出的顺序在构造函数之前发生。

确定性和可预测性

您只应在单个构造函数中的单个位置初始化实例成员。

依赖默认值会导致难以跟踪错误,并使测试成为噩梦,但是未分配的实例成员会像对IDE,编译器和运行时的烦恼一样脱颖而出。 不幸的是,对于像int这样的基元,它们默认为0 ,这可能不是您想要/不需要的。

更好的设计是:

 private final int j;

 public Foo(final int j) { this.j = j; }

这样可以避免在初始化时为j分配任何东西,而您不必担心它会发生变化。

假设您有这堂课

public class Test
{
    int i = 4;

    public Test()
    {
        System.out.println(i);
    }  
}

创建Test的实例时,输出为4 这意味着初始化首先进行。 然后调用构造函数。 因为如果构造函数是第一个,而i的初始化是第二个,则不会得到4作为输出。

int i = 0;

我是一个实例变量,因此将获得默认值0。因此,您无需显式分配0。

来问你的问题

 But my question is which variable first get initialized?

然后答案是i在j之前初始化。 因为如果您看到代码段的字节码,则首先创建对象,这将初始化您的实例变量,然后调用构造函数。

无论何时创建对象创建,都会先进行变量的声明,然后才定义变量。 在您的情况下,将首先声明“ j”变量,即类变量。此后,该值将在类的构造函数中分配给“ j”。

订购:-

  1. 首先执行静态初始化块。(如果有)
  2. 然后从main方法开始执行。

对于您的问题,我认为当i=0ij将会一起出现。 j为0(具有int默认值。)

因为在构造函数中,您只是在更改值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM