2011-08-09 227 views
6

可能重复:
Should I initialize variable within constructor or outside constructor初始化的声明VS在构造函数初始化

我想知道,这是一个更好的做法,为什么。我应该在声明时初始化类字段,还是应该在构造函数中执行它?鉴于这是一个简单的单行初始化。

class Dude 
{ 
    String name = "El duderino"; 

    Dude() { 
     // irrelevant code 
    } 
} 

class Dude 
{ 
    String name; 

    Dude() { 
     name = "El duderino"; 

     // irrelevant code 
    } 
} 

编辑:我知道那里的款式之一将在可能抛出异常执行初始化代码的情况下,可以优先于其他类似的情况。我在这里讨论的是两种风格完全相同的情况。两种方式都可以完成同样的任务。那我应该用那个?

回答

4

如果成员可以通过访问器(“setter”方法)设置,我更喜欢第一种风格。它提供了一个提示,即初始化值是构造时的默认值。

如果可以在构造过程中指定成员,我通常会使用较少的参数将默认值从构造函数传递给适当的构造函数。例如,

final class Dude { 

    private final String name; 

    Dude() { 
    this("El Duderino"); 
    } 

    Dude(String name) { 
    this.name = name; 
    } 

} 
+0

这听起来很合理。但是我所说的是那些将要被初始化的字段,即从构造函数中检索的数据不会被使用。像初始化一个空的内部列表来存储子元素。你还会在构造函数中初始化它吗? – amrhassan

+0

@amrhassan - 在这种情况下,我不会在声明它时初始化它,并且我会声明它是'final'。 – erickson

+0

我可以看到在你的例子中使它成为'final'的原因,但是如果有setter'setName(String name)'... – knownasilya

0

第一个通常用于初始化静态变量,应该仅用于此目的。

在这种情况下,您应该使用第二种方法。

如果我错了,请纠正我。

+0

第一个工作正常没有静态字段。这是第二个糖的合成糖。 – amit

+0

是的,我知道你的意思。但是如果你已经使用了C++,你就会知道他没有做第一个初始化静态变量的东西,并且为了确切的目的而将它添加到了Java中 - 初始化静态变量。因此,它必须用于它的目的。 – mtahmed

+0

我没有理由为静态变量保留第一个样式。你能提供任何推理吗? – erickson

0

为了保持一致性,最好在构造函数中声明变量。一个变量可能需要类似循环或if-else语句来初始化它,如果不将该操作放置在方法内部,则不能在声明中完成。

这条规则的例外是静态变量,它应该在构造函数之外声明。

+0

我们可以使用初始化块初始化否则只能在方法或构造函数内初始化的字段。 – emory

0

单行声明不能包含复杂的初始化逻辑。

如果初始化变量:

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 
{ 
    MyClass anObject; 

    { 
     try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/} 
    } 
} 

我发现,后者使对更难理解代码,作为声明和初始化从彼此分开,并且初始化并在构造由显影剂编码(虽然没有在运行时没有差别不会发生)。

对于涉及字段初始化的其他复杂例程也是如此。例如,如果你打算初始化ArrayCollection并设置阵列/收集到一些默认值的内容,那么你应该在构造函数中这样做:

class AnotherClass 
{ 
    Integer[] integers; 

    AnotherClass() 
    { 
     this.integers = new Integer[10]; 
     for(Integer integer: integers) 
     { 
      integer = Integer.MIN_VALUE; 
     } 
    } 
} 
+1

实际上,人们也可以在这里使用初始化块,所以即使在这种情况下,构造函数也不是唯一的可能方式 – Voo

+0

是的,这可能太令人困惑了。但这是我的看法。将编辑。 –