繁体   English   中英

Java - 将实例变量传递给 this() 方法

[英]Java - passing instance variables to this() method

我正在学习使用this()调用重载的构造函数并遇到了这个限制:

您不能在调用 this() 时使用构造函数的 class 的任何实例变量

例如:

class Test{
    int x;

    public Test() {
        this(x); //Does not compile
    }

    public Test(int y) {}

    void method1() {
        method2(x); //OK
    }

    void method2(int y) {}
}

我知道不需要将实例字段传递给构造函数,因为它默认是可见的。 但是,为什么同样的限制不适用于实例方法?

Java 中还有另一个要求:构造函数调用(使用this()必须首先在任何构造函数中执行。构造函数将初始化 object。

之后,实例字段在这些初始调用之后被初始化。 因此,由于字段值现在已经很好地定义,您可以将它们用于任何事情,包括调用其他方法。

但是,在初始构造函数调用之前,这些字段位于未定义的 state 中,不能用作其他构造函数调用的参数。


对于这些你需要查看 JLS 的东西:

  1. 如果此构造函数以对同一 class(使用 this)中的另一个构造函数的显式构造函数调用(第 8.8.7.1 节)开始,则评估 arguments 并使用这五个相同的步骤递归地处理该构造函数调用。 如果该构造函数调用突然完成,则此过程出于相同原因而突然完成; 否则,继续执行步骤 5。

  2. 执行此 class 的实例初始化程序和实例变量初始化程序,将实例变量初始化程序的值分配给相应的实例变量,按照它们在 class 的源代码中以文本形式出现的从左到右的顺序。 如果执行这些初始化程序中的任何一个导致异常,则不会处理更多初始化程序,并且此过程会突然完成相同的异常。 否则,继续执行步骤 5。

所以实例变量只有在构造函数调用后才被初始化。 这是有道理的,因为首先为其分配默认值(零或空)然后从构造函数中为其分配另一个值会很奇怪。

构造函数构造实例。 所以我们不应该期望实例变量x在构造函数启动时被初始化。
另一方面,实例方法已经可以访问实例变量。 没有理由禁止将它们作为参数传递给另一个实例方法。

然而,当我们开始进一步思考它时,对构造函数的限制就不再那么有意义了。 我们也可以在那里访问实例变量,那么为什么我们不能将参数传递给另一个构造函数呢?

所以一个更好的问题是:为什么我们不能传递一个实例变量来从我们的构造函数中调用我们的构造函数的重载?
这个问题得到了很好的回答。 它甚至可以被认为是重复的(但由于这个借口是理解原因所必需的,所以我写了一个答案而不是简单地标记)。

在构造函数外部的 class 主体中声明和初始化的实例字段,例如您的int x; 在调用重载的构造函数之后分配。

您可以将其与我们对调用构造函数重载的其他限制进行比较:我们只能在构造函数的第一行这样做。 就在一开始。 然后,变量尚未初始化。 但是它们是在第一个非构造函数调用指令之前初始化的。


可以在这里那里找到为什么这个其他限制是一个东西的切线信息:

因为 JLS 是这么说的。 是否可以以兼容的方式更改 JLS 以允许它? 是的。

从历史上看,this() 或 super() 必须在构造函数中排在第一位。 这种限制从未流行过,并且被认为是任意的。 有许多微妙的原因,包括对 invokespecial 的验证,导致了这种限制。 多年来,我们已经在 VM 级别解决了这些问题,以至于考虑解除这个限制变得切实可行,不仅是为了记录,而是为了所有构造函数。

您应该教育 class 订单初始化费: https://www.baeldung.com/java-initialization

调用 class 构造函数时,不会初始化int x字段。 您可以在构造函数中设置(初始化)`int x',但不能调用它。

我不知道为什么你必须遵循这种方式,但你可以使用static字段: class Test{ static int x;

    public Test() {
        this(x); //Does not compile
    }

    public Test(int y) {}

    void method1() {
        method2(x); //OK
    }

    void method2(int y) {}
}

您还可以在调用它的行中初始化 static 字段,

static int x =4/2;

或在 static 块中:

static int x;
static {
    x = 4/2;
}

暂无
暂无

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

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