2011-08-09 97 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

是的,這可能太令人困惑了。但這是我的看法。將編輯。 –