简体   繁体   English

在构造函数中,指定的最终对象字段是否仍然为空?

[英]Is it true that the assigned final object field may still be null inside a constructor?

Is it true that the assigned final object field may still be null inside a constructor? 在构造函数中,指定的最终对象字段是否仍然为空?

class MyClass {
  private final Object obj = new Object();
  public MyClass() {
    System.out.println(obj); // may print null?
  }
}

if yes, isn't this a bug? 如果是的话,这不是一个错误吗?

As discussed by other answers, no, that can not happen. 正如其他答案所讨论的那样,不,这不可能发生。 With an assigned final static field, however, it can. 但是,对于指定的最终静态字段,它可以。

class MyClass {
  private static MyClass myClass = new MyClass();
  private static final Object obj = new Object();
  public MyClass() {
    System.out.println(obj); // will print null once
  }
}

This is not possible as the as all initializers run before the constructor is invoked . 这是不可能的,因为所有初始化程序在调用构造函数之前运行

Variable initializers like you have private final Object obj = new Object(); 像你这样的变量初始化程序有private final Object obj = new Object(); run before the constructor is invoked. 在调用构造函数之前运行。 This is also true of initialisation blocks static or otherwise. 初始化块静态或其他也是如此。

One thing to watch out for when using initializers is that initializers can't make forward references When you write an initializer, you cannot refer to any instance variables declared textually after the variable being initialized. 使用初始化程序时要注意的一点是初始化程序无法进行正向引用在编写初始化程序时,不能引用在初始化变量之后以文本方式声明的任何实例变量。

The initializer Object obj = new Object(); 初始化器Object obj = new Object(); will run before the code inside the constructor, so obj cannot be null . 将在构造函数内部的代码之前运行,因此obj不能为null

Note that this would not compile if you did not initialize obj anywhere. 请注意,如果您没有在任何地方初始化obj则无法编译。

Works for me: 适合我:

$ cat MyClass.java
class MyClass {
    private final Object obj = new Object();
    public MyClass() {
        System.out.println(obj); // may print null?
    }
    public static void main(String[] args) { new MyClass(); }
}
$javac MyClass.java; java MyClass
java.lang.Object@19908ca1

All field initializers are copied by the compiler into the begining of all constructors. 所有字段初始值设定项都由编译器复制到所有构造函数的开头。

However, under the Java 5 memory model, if you let the this reference 'escape' before the end of the constructor, other threads can see uninitialized values of final fields (so could see null in this case). 但是,在Java 5内存模型下,如果在构造函数结束之前让this引用“转义”,则其他线程可以看到final字段的未初始化值(因此在这种情况下可能会看到null )。

With a simple example like yours, nothing bad can happen. 有了像你这样的简单例子,没有什么不好的事情可以发生。 However, it is possible for a final field to be visible as uninitialised if you use questionable practices such as calling an overridable method in your constructor. 但是,它可能的final场为未初始化如果使用可疑行为,如调用构造函数可重写的方法是可见的。

For example, the following program prints "My favourite colour is null", even though it references the final variable favouriteColour , which is set to "blue" in the constructor. 例如,以下程序打印“我最喜欢的颜色为空”,即使它引用了最终变量favouriteColour ,它在构造函数中设置为"blue"

abstract class SuperClass {
    final String favouriteColour;

    SuperClass() {
        announceFavouriteColour();
        favouriteColour = "blue";
    }

    abstract void announceFavouriteColour();
}

public class FinalTest extends SuperClass {
    void announceFavouriteColour() {
        System.out.println("My favourite colour is " + favouriteColour);
    }

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

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

相关问题 即使在DynamicReports中分配了数据集,子报表字段仍然为空 - Subreport field is still null even if the dataset is assigned in DynamicReports 最终变量可能已被分配 - Final variable may already have been assigned 对于接口,不能分配最后一个字段 - The final field cannot be assigned, for an interface 如果传递最终对象,是否仍应检查null? - If final object is being passed, should null still be checked? Spring:在实例化最终字段的自动装配构造函数中使用application属性 - Spring: Use application property inside an autowired constructor that instantiate a final field 这两个构造函数上的错误 空白的最终字段 errorCodes 可能尚未初始化 - error on this two constructor The blank final field errorCodes may not have been initialized 在构造函数中初始化一个静态 final 字段 - Initialize a static final field in the constructor 可能已经分配了最终的局部变量cb - The final local variable cb may already have been assigned 空白的final字段可能尚未初始化 - the blank final field may not have been initialized Arraylist 在构造函数内部正确分配,但在 Android Studio 服务外部时为 null - Arraylist being assigned correctly inside a constructor but is null when it is outside in a Android Studio Service
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM