Java 在声明中初始化与在构造函数中初始化
可能重复:Java 在声明中初始化与在构造函数中初始化,java,Java,可能重复: 我想知道,哪一种做法更好,为什么。我应该在声明时初始化类字段,还是应该在构造函数中初始化?考虑到这是一个简单的单行初始化 class Dude { String name = "El duderino"; Dude() { // irrelevant code } } vs Edit:我知道在某些情况下,其中一种样式比另一种样式更受欢迎,比如在执行可能引发异常的初始值设定项代码时。我这里说的是两种风格完全相同的情况。两种方法都可以完成相同
我想知道,哪一种做法更好,为什么。我应该在声明时初始化类字段,还是应该在构造函数中初始化?考虑到这是一个简单的单行初始化
class Dude
{
String name = "El duderino";
Dude() {
// irrelevant code
}
}
vs
Edit:我知道在某些情况下,其中一种样式比另一种样式更受欢迎,比如在执行可能引发异常的初始值设定项代码时。我这里说的是两种风格完全相同的情况。两种方法都可以完成相同的任务。那么我应该使用哪一个呢?第一个通常用于初始化静态变量,并且应该仅用于此目的 在这种情况下,您应该使用第二种方法
如果我错了,请纠正我。为了保持一致性,最好在构造函数中声明变量。变量可能需要一个循环或if-else语句之类的语句来初始化它,如果不将操作放在方法内部,就无法在声明中进行初始化
此规则的例外是静态变量,应在构造函数外部声明。单行声明不能包含复杂的初始化逻辑 如果将变量初始化为:
class AnotherClass
{
MyClass anObject = new MyClass(); //MyClass() throws a checked exception.
}
然后,您会发现无法在单行中提供初始值。您需要将这样的代码放在一个块中,很明显,它位于构造函数(或非静态初始化块)中:
使用构造函数:
class AnotherClass
{
MyClass anObject;
AnotherClass()
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
class AnotherClass
{
Integer[] integers;
AnotherClass()
{
this.integers = new Integer[10];
for(Integer integer: integers)
{
integer = Integer.MIN_VALUE;
}
}
}
使用初始化块:
class AnotherClass
{
MyClass anObject;
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
我发现后者导致代码不易理解,因为声明和初始化彼此分离,并且初始化不会发生在开发人员编写的构造函数中(尽管在运行时没有区别)
这同样适用于涉及字段初始化的其他复杂例程。例如,如果要初始化数组
或集合
,并将数组/集合的内容设置为某个默认值,则应在构造函数中执行此操作:
class AnotherClass
{
MyClass anObject;
AnotherClass()
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
class AnotherClass
{
Integer[] integers;
AnotherClass()
{
this.integers = new Integer[10];
for(Integer integer: integers)
{
integer = Integer.MIN_VALUE;
}
}
}
如果只能通过访问器(setter方法)设置成员,我更喜欢第一种样式。它提示初始化值是构造时的默认值
如果可以在构造过程中指定成员,我通常会将默认值从参数较少的构造函数传递给适当的构造函数。比如说,
final class Dude {
private final String name;
Dude() {
this("El Duderino");
}
Dude(String name) {
this.name = name;
}
}
第一种方法适用于非静态字段。这是第二种合成糖。是的,我知道你的意思。但是如果你已经使用C++,你会知道在初始化静态变量的过程中,他没有做过什么事情,而且为了精确的目的,它被添加到java中——初始化静态变量。因此,它必须用于它的用途。我认为没有理由为静态变量保留第一种样式。你能提供任何理由吗?另一个原因是这样的声明可能会与常量声明混淆。我不同意。使用构造函数意味着a)第一眼看不到变量的值(必须查看所有构造函数,看看它是否总是初始化为相同的值)和b)必须为编写的每个构造函数编写初始化。实际上,这里也可以使用初始值设定项块,因此即使在这种情况下,构造函数也不是唯一可能的方法。是的,这可能太令人困惑了。但这是我的意见。将进行编辑。我们可以使用初始化块初始化字段,否则这些字段只能在方法或构造函数中初始化。这听起来很合理。但我所说的是,无论哪种方式,字段的初始化都是相同的,也就是说,不会使用从构造函数检索的数据。类似于初始化用于存储子元素的空内部列表。你还会在构造函数中初始化它吗?@amrhassan-在这种情况下,我会在声明它时初始化它,并将它声明为
final
。在你的示例中,我可以看到使它成为final
的原因,但是如果有一个settersetName(字符串名)
。。。