2009-06-13 19 views
3

例如:調用它的構造函數而不是構造函數時設置實例的變量是否有什麼好處?

public class Foo { 
    private int bar = 42; 

    Foo() {} 
} 

VS

public class Foo { 
    private int bar; 

    Foo() { 
     bar = 42; 
    } 
} 

有兩種方法之間的成本/效益?我可以看到它發揮作用的唯一辦法就是在這樣的情況下(如你的第二個構造設置兩次值):

public class Foo { 
    private int bar = 42; 

    Foo() {} 

    Foo(int in) { 
     bar = in; 
    } 
} 

VS(其中無論哪種方式,你只設置一次)

public class Foo { 
    private int bar; 

    Foo() { 
     this(42); 
    } 

    Foo(int in) { 
     bar = in; 
    } 
} 

我錯過了什麼嗎?這種做法有沒有內在的價值?

編輯

好吧,我知道這些都是functionaly等價的,如果有一個比其他相關的任何顯著的處理成本是什麼,我試圖找出是。似乎它應該是可以忽略的,至多,但我想確認我的懷疑。

編輯2

我也意識到,手動設置它們消除了啓動邏輯的可能性。這就是我選擇這樣簡單的例子的原因。我編輯了問題文本,以反映我感興趣的是效率。

回答

11

這兩種方法是等價的。隨着中說,我會添加兩件事情:

  1. 這往往是更多的與最終變量的問題,因爲很明顯,你在你的第三個片段你只能設置一次即可;和
  2. 嘗試鏈接你的構造函數。

(2)我認爲這是一個更好的版本:

public class Foo { 
    private int bar; 

    Foo() { 
     this(42); 
    } 

    Foo(int in) { 
     bar = in; 
    } 
} 

通過鏈接構造函數,你可以得到一個不錯的DRY默認默認值(不要重複自己)的一種方式,特別是當處理可能具有默認參數,各種允許類型的參數和非平凡初始化的幾個參數。理想情況下,只有一個或者兩個你的構造函數應該有重要的邏輯。其餘的應該鏈接到另一個構造函數。

如果你想使類不可變的(如喬希布洛赫說,贊成不變性),則:

public class Foo { 
    private final int bar; 

    Foo() { 
     this(42); 
    } 

    Foo(int in) { 
     bar = in; 
    } 
} 

最後它可能是值得的42靜態最終常數(私有或公共,如適用)。

+0

很不好說! – neesh 2009-06-13 23:27:04

+0

我意識到他們在功能上是相同的......我猜想我想弄清楚的是對於另一個人是否有任何好處。我正在爲手機編程,並試圖在合理範圍內儘可能「高效」。 – 2009-06-13 23:34:33

0

個人我更喜歡第一種方式,因爲它更清楚var最初的值。

0

將字段設置爲構造函數中默認值的主要風險是人們開始添加多個構造函數並且不保持字段一致。

對遺留Java代碼我自己的(不科學的)經驗是,如果有兩個以上的構造函數和兩個以上的字段,80%的時間將不能正確初始化。

2

在構造函數中初始化變量有很多好處。有時初始化需要邏輯,如果變量的值如第一個例子那樣設置,則不能完成。然而其他人對可維護性的觀點是有效的。

但是Java爲我們提供了初始化塊。初始化塊被編譯器複製到每個構造函數中。所以,如果你所擔心的構造函數是不一致的,那麼你可以這樣做:

public class Foo { 
    private int bar; 

    //initializer block 
    { 
     //initializing code here 
    } 

    Foo() { 

    } 
} 

,你有第二個選擇是鏈構造函數由克萊描述。

0

當你的成員變量是final的,並且你有一個從父類的構造函數調用的方法時(這是一個不好的做法,請不要這麼做),有一點區別。

下面的代碼的輸出是:

early = 42 
late = 0 

下面是測試代碼:

class Test { 

    private static class Base{ 

     Base() { 
      doInConstructor(); 
     } 

     protected void doInConstructor() { 

     } 
    } 

    private static class Derived extends Base { 
     final int early = 42; 
     final int late; 

     Derived() { 
      late = 84; 
     } 

     protected void doInConstructor() { 
      super.doInConstructor(); 
      System.out.println("early = " + early); 
      System.out.println("late = " + late); 
     } 
    } 

    public static void main(String[] args) { 
     new Derived(); 
    } 
} 
相關問題