在构造函数内部或其外部创建成员有什么区别(如果有的话)?
示例1:
public class Person
{
List<Person> friends = new List<Person>();
public Person()
{
}
}
示例2:
public class Person
{
List<Person> friends;
public Person()
{
friends = new List<Person>();
}
}
我以C#为例,但这适用于任何oop语言。
两者之间是否存在实际差异?我已经将示例2描述为一种更清洁的方式来实现它。
答案 0 :(得分:1)
在C#中,我认为这不重要。在构造实例时,将在构造函数运行之前初始化在声明处初始化的变量(如果有)。 如果没有这些变量,那么它们之间就没有功能差异
为了更好地参考,请查看: - Best Practice: Initialize class fields in constructor or at declaration?
引用一条从上面的链接中非常重要的一行(由Quibblesome说)
就最佳实践而言,前者不易出错 后者因为有人可以轻松添加另一个构造函数而忘记了 链它。
答案 1 :(得分:1)
在此处抄袭Oracle Java教程:http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
如您所见,您通常可以在其声明中为字段提供初始值:
public class BedAndBreakfast {
private boolean full = false;
}
当初始化值可用且初始化可以放在一行时,这很有效。然而,这种形式的初始化由于其简单性而具有局限性。如果初始化需要一些逻辑(例如,错误处理或for循环来填充复杂的数组),则简单的赋值是不合适的。实例变量可以在构造函数中初始化,可以使用错误处理或其他逻辑。
答案 2 :(得分:1)
我将尝试从Java的角度分析它。除非您的变量/成员是static
,否则无关紧要。示例2有时被称为lazy initialization
,您将推迟朋友列表的初始化,直到调用构造函数。但是,朋友不是static
编译器会以与示例2类似的方式处理您的示例1.来自HERE
然而,字段声明不是任何方法的一部分,所以它们 不能像声明一样执行。相反,Java编译器 自动生成实例字段初始化代码并放入它 在类的构造函数或构造函数中。初始化 代码按照它出现的顺序插入到构造函数中 源代码,这意味着字段初始值设定项可以使用初始值 在它之前声明的字段的值。
因此编译器只是将您的示例1代码转换为示例2,以便可以以类似的方式初始化它。