【问题标题】:When does java execute class-level field assignments?java什么时候执行类级别的字段赋值?
【发布时间】:2020-07-14 19:32:57
【问题描述】:

我认为自己在编程方面有点初学者/中级;大多数时候,我似乎知道如何编写代码,但我并不确切知道 java 用它做了什么。有时我有一个在构造函数中分配的字段:

public class MyClass {
     public int x;
     
     MyClass() {
       x = 5;
     }
}

...据我所知,当创建 MyClass 的新对象时,x 被设置为 5。但是,有时我会在任何构造函数或函数之外分配字段:

public class MyClass {
     public int x = 5;
     public static MyOtherClass y = new MyOtherClass();
 
     public MyClass() {

     }
}

java 究竟什么时候运行这些分配?它们是在创建 MyClass 对象时还是在此之前完成的?如果我引用一个静态变量,例如“y”:

public class MyThirdClass {
     public MyOtherClass z = MyClass.y;
}

是在我第一次引用它时分配了“y”,还是在此之前 Java 已经完成了它?在这种情况下,在创建 MyClass 的新对象后无法分配“y”,因为我还没有为它创建任何对象。那么,所有这些在构造函数和方法之外的字段分配是在程序运行时一次性完成,还是在首次引用/需要它们时分配?还是其他时间?感谢您提供这方面的任何信息。

【问题讨论】:

  • 它们被视为初始化块的一部分(没有“名称”的{..})。例如int val1 = 1; int val2; { val2=2; } int val3 = 3; 可以被认为是int val1; int val2; int val3; {val1=1; val2=2; val3=3}。初始化块在每个构造函数的开始处被复制(好吧,在它的super(..) 调用之后,隐式或显式)。因此,如果您有int val = 42; 并且在构造函数中您将编写MyClass(){val = 10;},那么它将像编写MyClass(){super(); {val=42;} val=10;} 一样被编译。因此,构造函数中的值将覆盖直接在字段中设置的值。

标签: java class field


【解决方案1】:

成员变量初始化器如下:

public class MyClass {
     public int x = 5;
     public int y;
     
     MyClass() {
       y = 6;
     }
}

在调用超级构造函数(隐式或显式)的所有构造函数中内联,在调用超级构造函数和构造函数主体的其余部分之间:

public class MyClass {
     public int x;
     
     MyClass() {
       super();
       x = 5;
       y = 6;
     }
}

不仅仅是成员变量初始化器:成员变量初始化器基本上就像成员声明,​​后面跟着一个实例初始化器:

public int x = 5;

// is the same as

public int x;

{
  x = 5;
}

类中的所有实例初始化器都内联到超级调用构造函数中,按照它们在类中声明的顺序。

【讨论】:

  • 明白了,谢谢。如果它们是静态的,并且构造函数永远不会被调用呢?
猜你喜欢
  • 1970-01-01
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-12
  • 1970-01-01
  • 2015-03-03
  • 2017-02-20
相关资源
最近更新 更多