2012-01-14 87 views
2

是否有之間的差異(在Java或C#):什麼是設置和實例化類級別變量的正確方法?

public class Foo { 
    Bar1 bar1; 
    Bar2 bar2; 

    public Foo(Bar1 bar1, Bar2 bar2) { 
    this.bar1 = bar1; 
    this.bar2 = bar2; 
    } 
} 

而且

public class Foo { 
    Bar1 bar1 = null; 
    Bar2 bar2 = null; 

    public Foo(Bar1 bar1, Bar2 bar2) { 
    this.bar1 = bar1; 
    this.bar2 = bar2; 
    } 
} 

對於對象,它不應該不管你是否指定空或不是 - 這是隱含的,對不對?

我的老闆堅持分配每個值null。對於字符串,我明白分配String str = "",因爲那裏存在很大的差異,但我不太確定爲什麼巨大的交易對象。

而且,它是不好的做法,做到以下幾點:

public class Foo { 
    Bar1 bar1 = new Bar1(); 
    Bar2 bar2 = new Bar2(); 

    public Foo(Bar1 bar1, Bar2 bar2) { 
    this.bar1 = bar1; 
    this.bar2 = bar2; 
    } 
} 
+1

Uuughh當他們說他們的老闆堅持這個或那個沒有任何區別的編程細節時,我感到非常糟糕。作爲一名初級程序員進行月光照明的開發經理,並討論無用的語義。不要忍受它,姐妹和兄弟。 – 2012-01-14 02:45:03

+0

實際上,我不明白分配'str =「」',除非有充分理由說它應該是空字符串。至少如果你錯過了將它從null改爲bug的話,這個bug可能會更快。或者一個字符串應該是空的,或者它不應該,隨機地拋出'=「」'只是破壞。 – 2012-01-14 03:09:12

回答

4

沒有必要明確初始化實例變量爲默認值。在Java和C#中,實例變量在創建實例時被賦予默認值。參考類型已在運行構造函數的主體之前爲 null。 int已經是0等等。在第一個代碼片段中,bar1和bar2已經是空的。沒有需要明確說明它,如在第二個片段。

在第二個示例(第三個片段)中,如果您所做的只是在構造函數中使用另一個引用進行覆蓋,則絕對不需要將實例變量實例化爲new Bar1();

當構造函數尚未立即用提供的參數覆蓋它時,您可能想要將默認值設置爲默認類型默認值以外的值時,將其初始化爲值。但將其設置爲默認值只是多餘的。但是,如果它可以幫助你的老闆或者團隊的其他成員理解這些默認值是什麼,那就這樣吧。

+0

如果您有多個構造函數,或者沒有立即從構造函數中分配所有值,這是否會更改? – Cody 2012-01-14 02:36:17

+0

我已經擴大了答案(並且刪除了關於單個構造函數的措詞),希望能夠使其更清晰。實例成員總是初始化爲默認值,您不必明確地執行此操作。 – 2012-01-14 02:43:52

2

如果您要在構造函數中指定一個類字段,通常不會在字段聲明中進行任何賦值。 (如果你的構造分配領域,雖然,這是一個不同的故事。)

1

前兩個之間的唯一區別是,爲了前者是意圖更加清晰。

雖然我知道bar1和bar2會被初始化爲空(至少在概念上,希望它在兩種情況下都會被優化),但很明顯,它們的意圖是它們不是null,而是設置爲它們的值在構造函數中給出。

但在第二種情況下,意圖不明確。開發人員明確地將它們設置爲空,所以大概是開發人員希望它們由於某種原因而爲空。然後開發人員將它們設置爲唯一可見代碼路徑中的其他內容。當我看到我無法理解其意圖的代碼時,有四種可能性。

  1. 開發者是個白癡。
  2. 代碼經歷了一些變化,雖然顯式設置爲null是必要的,但它不再是,而這只是早期代碼的遺留問題。
  3. 開發出了一個錯誤。
  4. 我沒有發現什麼。

我可以排除數字1,因爲我不適合白癡。如果我發現自己在與白癡打交道,我會拋光我的簡歷。

我和其他三個人在一起。我不傲慢,所以我不排除4,直到我確定。如果我不能快速詢問有問題的開發者,那麼我會浪費一些時間確保4不是這種情況。如果我可以問開發者,我可能會浪費我的一些時間和他們的時間。儘管如此,它並不是真的浪費,因爲2,3和4,我需要知道哪種情況,因爲只有這樣,我才能確定我理解代碼,並且沒有與初始化相關的錯誤。

第三種情況更糟糕。假設一切順利,那麼唯一真正的效果就是編譯器或抖動不會優化掉故意插入的cruft,這會對性能造成很小的影響。但是,因爲一切都不順利,也許你剛剛發現了一個難以發現的錯誤。

編輯:

這是假設,有沒有副作用創建對象。如果有的話,那麼第三種情況可能是從相當浪費到徹底危險的事情。

1

由於已經提示1和2之間沒有區別,只需要提供明確指定'空'值的情況。

考慮,

public class Foo 
    { 
     .... 
     public void DoSomething() 
    { 
     string someValue; 

     if (someValue == null) 
     { 
      Console.WriteLine("SomeValue must not be null"); 
     } 
     else 
     { 
      Console.WriteLine(someValue); 
     } 
    } 
    } 

你有什麼期望得到的DoSomething的輸出? 這是一個編譯時錯誤:'使用未分配的局部變量'somValue'。

因此,在這種情況下,它是強制性的,因此具有someValue = null是有意義的。但是,對於成員字段,它並不是因爲對象構造函數爲所有成員字段分配默認值(默認值(T))。

相關問題