在构造函数或者声明中初始化类字段?
我最近一直在用Cand Java编程,我很好地知道初始化我的类字段的最佳位置。
我应该在申报时这样做吗?:
public class Dice { private int topFace = 1; private Random myRand = new Random(); public void Roll() { // ...... } }
或者在构造函数中?:
public class Dice { private int topFace; private Random myRand; public Dice() { topFace = 1; myRand = new Random(); } public void Roll() { // ..... } }
我真的很好奇你们中的一些资深人士认为这是最佳做法。我要保持一致,并坚持一种方法。
解决方案
回答
我的规则:
- 不要使用声明中的默认值进行初始化(" null"," false"," 0"," 0.0")。
- 如果没有用于更改字段值的构造函数参数,则首选在声明中进行初始化。
- 如果字段的值由于构造函数参数而改变,则将初始化放入构造函数中。
- 在练习中保持一致(最重要的规则)。
回答
假设示例中为类型,则绝对希望在构造函数中初始化字段。例外情况是:
- 静态类/方法中的字段
- 键入为静态/最终/等的字段
我总是将类顶部的字段视为目录(此处包含的内容,而不是其使用方式),并将构造函数作为引言。方法当然是章节。
回答
如果我告诉你,那要取决于什么?
通常,我会初始化所有内容并以一致的方式进行操作。是的,它过于明确,但维护起来也更容易一些。
如果我们担心性能,那么我只初始化需要做的事情,然后将其放在最能带来回报的区域。
在实时系统中,我质疑我是否甚至需要变量或者常量。
在C ++中,我经常在任何地方几乎都没有初始化,然后将其移动到Init()函数中。为什么?好吧,在C ++中,如果要初始化的对象在构造对象时可能引发异常,则可能会导致内存泄漏。
回答
我通常尝试使用构造函数,除了获取依赖项并使用它们初始化相关实例成员外,什么也不做。如果我们要对课程进行单元测试,这将使生活更轻松。
如果要分配给实例变量的值不受要传递给构造函数的任何参数的影响,则在声明时将其分配。
回答
在Cit中没有关系。我们提供的两个代码示例完全相同。在第一个示例中,Ccompiler(或者它是CLR?)将构造一个空的构造函数并初始化变量,就像它们在构造函数中一样。
如果已经有一个构造函数,那么任何"之上"的初始化都将移到它的顶部。
从最佳实践的角度来看,前者比后者更不容易出错,因为有人可以轻松地添加另一个构造函数而忘记链接它。
回答
在声明中设置值会有一点性能上的好处。如果在构造函数中设置它,则实际上它被设置了两次(首先设置为默认值,然后在ctor中重置)。
回答
Cdiffers的语义与Java略有不同。在Cassignment中,声明是在调用超类构造函数之前执行的。在Java中,此操作立即完成,然后允许使用" this"(对匿名内部类尤其有用),这意味着这两种形式的语义确实匹配。
如果可以,请将字段定为final。