Java 先执行哪一个新命令?在构造函数中还是在外?

Java 先执行哪一个新命令?在构造函数中还是在外?,java,constructor,Java,Constructor,如果我定义如下所示的类: public class myClass { private x = new anotherClass(); private y; public myClass() { y = new anotherClass(); } } 公共类myClass{ private x=新的另一个类(); 私家侦探; 公共myClass(){ y=新的另一个类(); } } 哪个变量将更早地获取实例?x还是y 而且,在构造函数之外分配

如果我定义如下所示的类:

public class myClass { private x = new anotherClass(); private y; public myClass() { y = new anotherClass(); } } 公共类myClass{ private x=新的另一个类(); 私家侦探; 公共myClass(){ y=新的另一个类(); } } 哪个变量将更早地获取实例?x还是y


而且,在构造函数之外分配变量是否不值得推荐

代码中的变量具有类型,但在调用构造函数之前先实例化
x
。(对构造函数上的
x
执行空检查以找出答案)


至于推荐,由你决定。有一件事,例如在JavaBeans中,因为我通常不编写默认的公共构造函数(没有参数),所以我倾向于在声明中初始化一些字段(如果它们需要不为null)。否则,我将在构造函数上实例化它们。

我建议您进行测试,而不是仅仅从其他人那里得到答案:

使另一个类的构造函数打印通过的字符串

public class myClass {
    private anotherClass x = new anotherClass("outside constructor");
    private anotherClass y;

    public myClass() {
        y = new anotherClass("inside constructor");
    } 
}

然后你可以告诉我们

执行顺序为:

  • 超类构造函数(或链接到同一类的构造函数)
  • 实例变量初始值设定项(在代码中指定给
    x
    的表达式)
  • 构造函数主体(在代码中指定给
    y
    的语句)
包含详细信息


是否在构造函数中分配变量取决于您-我非常喜欢一条经验法则,即如果初始值不依赖于任何构造函数参数,并且对于所有构造函数始终相同,则使用变量初始值设定项。否则,将其分配到构造函数中。

x
当然,因为如果你对
x
进行空检查,你会发现它在构造函数中不是空的。你的句子是正确的,但你的推理对我来说毫无意义。执行检查意味着在此特定情况下,
x
不为空。这可能是因为变量是在构造函数之前声明的,或者是其他什么。。。。阅读JLS是唯一确定答案的方法。测试将告诉您它在特定情况下的功能。。。但这并不能保证行为是明确的,也不能保证在其他情况下会发生什么。我更喜欢检查这些东西的规格。@Jon,我的观点是,尽管我的第一个选择(我试图分享的观点)是自给自足,并尝试自己弄清楚会发生什么。@davin:是的,这是合理的。测试/探索和规范咨询的结合通常效果良好。我同意@Jon的观点——通过阅读教科书学习比通过随机实验学习更可靠。试图自己解决问题的麻烦在于你不一定知道要做什么样的实验。@Stephen,更可靠,绝对!但是你告诉一个刚刚掌握OO和编程基础的初学者阅读语言规范,看看他们从中得到了多少——并不是每个人都准备好深入研究。我也看不出这有什么随机性。有一个特殊的案例正在测试中,没有讨论任何类型的随机分布。我不是在提倡这是精通一门语言的一种方式,我是在提倡这是一个很好的第一步,看看会发生什么,了解语言(是的,一个具体的实现)的行为,我不理解。如果超类的构造函数首先执行,为什么我们可以通过“super()”在子类的构造函数中调用它?无论是否显式调用超类构造函数,它总是作为子类构造函数的第一个方法调用。是的,子类首先被调用,但超类首先完成。@Lai:它被表示为构造函数体中的第一条语句的事实有点误导。我更喜欢C#方式,在构造函数主体之前指定它——这使它更清楚地说明了正在发生的事情(尽管那里的顺序略有不同)。您也不能在任何时候只执行超类构造函数,它必须是正文中的第一条语句。@Lai Yu Hsuan-调用super()完全没有必要,除非您需要调用带参数的超类构造函数。@Lai:不,除非您指定超类构造函数,否则它将始终尝试调用无参数的超类构造函数。构造函数参数不会自动传递。