java - 在构造函数结束之前如何引用/处理 "this"?

标签 java constructor this

我想到这个问题的具体使用如下,但是更笼统。

我有一个自定义的 JFrame 类,它还用作其组件的 ActionListener。所以我的构造函数看起来像下面这样:

private JButton myButton;

public MyCustomFrame() {
    super();
    myButton.addActionListener(this);
    // ... more stuff
}

我的问题是,这实际上是如何在幕后运作的?如果构造函数“创建”了 this 引用的对象,那么在构造函数返回之前如何使用 this?代码编译并运行良好(据我所知),因此该对象在某种意义上必须已经“存在”,但我担心这可能会导致无法预料的问题。将“部分构建”的引用传递给 addActionListener()(或者只是执行一般的逻辑)是否有任何危险?还是幕后发生了一些让我安全的魔法?

例如,那些没有默认值且必须由构造函数提供的东西怎么办?如果我声明了 private final String SOME_VALUE;,我知道这应该默认为 null,但是在提供常量之前,对象不应该完全形成构造函数中的值。那么,尽管该引用是最终的,但它的值可能会发生变化吗?

最佳答案

Java 语言规范指定了 instance creation 的步骤

[...]

Next, space is allocated for the new class instance. If there is insufficient space to allocate the object, evaluation of the class instance creation expression completes abruptly by throwing an OutOfMemoryError.

The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).

Next, the actual arguments to the constructor are evaluated, left-to-right. If any of the argument evaluations completes abruptly, any argument expressions to its right are not evaluated, and the class instance creation expression completes abruptly for the same reason.

Next, the selected constructor of the specified class type is invoked. This results in invoking at least one constructor for each superclass of the class type. This process can be directed by explicit constructor invocation statements (§8.8) and is described in detail in §12.5.

因此,当调用构造函数(它是一种方法)时,您的实例已存在并具有默认值。

对于 final 字段,如果您尝试访问它们,它们似乎也是默认的。例如

public class Driver {

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

    final int value;

    public Driver() {
        print(this);
        value = 3;
    }

    static void print(Driver driver) {
        System.out.println(driver.value);
    }

}

将打印 0。如果我能找到 JLS 条目,我会马上回来。

我找不到比上面的内容更具体的内容。也许在 4.12.4. final Variables

A final variable may only be assigned to once.

您可以理解为默认初始化将值设为 0 或 null 并且赋值会更改它。

关于java - 在构造函数结束之前如何引用/处理 "this"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20619192/

相关文章:

Java 十六进制字符串连接校验和

javascript - 对此,全局对象和全局范围的混淆

javascript - 检测除 not(this) 以外具有相同类别的其他项目

java - 将构造函数参数传递给 JAVA 方法

c++ - 调用默认构造函数的两种方式

java - 在 Java 中分配给这个的解决方法?

java - 提取相同字符的2个字符之间的字符串

java - 是否可以通过反射来确定方法参数是否是最终的?

java - 读取包含许多 json 对象的 Json 文件

C++11 从相同类类型的构造函数调用构造函数