2

这可能是一个“重复”,但我不知道如何搜索这个问题......

我在声明行初始化一个非静态成员变量:

public class A
{
    private B b = new B();
    ...
}

我正在这样做,而不是在默认构造函数中初始化这个变量:

public class A
{
    private B b;
    public A()
    {
        b = new B();
    }
    ...
}

两者之间有什么区别,除了(也许)前者不是“ANSI Java”或类似的东西?

对于上面的两个实现,我得到了两个不同的字节码(即两个不同的“类”文件),这让我相信可能存在运行时差异。

所以我想知道我是否有任何理由期望在运行时有什么不同。

谢谢

4

5 回答 5

3

第一个是同时声明和初始化。

在第二个示例中,您b没有初始化变量的声明,然后在构造函数中初始化变量...

功能差异可能会在您添加另一个构造函数的那一刻出现,在这种情况下,b即使在该构造函数中也应该初始化变量,否则,将会有很大的不同。

在第一种情况下,无论您实现了多少构造函数,都已初始化变量...

老实说,我不明白你怎么能假装拥有相同的字节码,为这种情况写两个不同的东西。

于 2014-01-12T17:16:54.463 回答
1

这种方法之间有一个小区别!

当在构造函数中声明变量时,有可能在一段时间后创建第二个构造函数并且该变量将被取消初始化。为了与之抗争,将此变量声明为最终变量-当然如果​​可能的话;)

其他差异不存在:)

public class A
{
    private B b;
    public A() {
        b = new B();
    }
    public A(int value) { // second constructor
    }
    ...
}

使用A a = new A(5);字段后bnull.

于 2014-01-12T17:15:06.610 回答
1

一般没有什么不同(意味着在构造函数外部和内部声明将表现不同)。只是提醒一下,在进入某些特定的构造函数之前,将首先运行外部初始化。例如:

class A {
  int a = 3;
  public A() {
     a = 4;  // now a = 4. not 3
  }
}

但是,我经常将它们用于不同的目的:

  1. 在构造函数中初始化变量使其更清晰,并帮助您初始化更复杂的东西。例如,放置一些逻辑代码,放置一个循环来添加项目,......在构造函数范围之外初始化时你不能这样做。

  2. 当您有许多重载构造函数,并且某些变量总是声明相同时。简单的“状态变量”,例如isExist isEmpty......我经常在构造函数范围之外进行初始化。因此,所有其他构造函数都不会做同样的事情。

于 2014-01-12T17:18:45.130 回答
1

没有区别,两种代码都运行良好。对于大班,我个人更喜欢第二种方式,而对于小班,我更喜欢第一种方式。

于 2014-01-12T17:19:43.443 回答
0

主要区别在于函数调用的顺序:

  • 在第一种情况下,方法B()在方法之前被调用A()
  • 在第二种情况下,方法A()在方法之前被调用B()

另一个区别是所有其他答案中所建议的内容......

当存在不初始化变量的非默认构造函数b时:

  • 在第一种情况下,即使使用该构造函数,变量b也会被初始化。
  • 在第二种情况下,无论何时使用该构造函数,都不会b初始化变量。
于 2014-01-12T17:45:36.167 回答