2009-11-29 34 views
11

這是一種可接受的編碼習慣嗎?使用帶有4個表達式的三元運算符

public class MessageFormat { 
    private static final Color DEFAULT_COLOR = Color.RED; 

    private Color messageColor = DEFAULT_COLOR; 

    public MessageFormat(Person person) { 
     Color color = person.getPreferredColor(); 
     messageColor = (color != null) ? color : messageColor; // this line 
    } 
} 

還是我最好的經典去......

if (color != null) { 
    messageColor = color; 
} 
+1

這是正式的__conditional operator__,[根據JLS](http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25)。從技術上講,可能還有其他三元運算符,就像有許多二元運算符一樣,儘管Java目前沒有。 – Pops 2010-06-01 18:33:13

回答

24

?:操作符的使用應該限制在使代碼更易讀的程度。一個典型的例子:

a = sprintf("There are %i green bottle%s on the wall.", i, (i==1?"":"s")); 

在這種情況下,如果你把它分成5的if/else行代碼會少可讀。

我通常會在整個操作符中放上括號,以便在閱讀時我會將其作爲一個單獨的值進行精神分析。

messageColor = (color != null ? color : messageColor); 

另一個變體是

messageColor = color || messageColor; 

在某些語言將評估爲「色,除非顏色的計算結果爲‘假’,在這種messageColor的情況下價值。在我看來,這應避免它可能會迷惑人。

最重要的是要保持一致,從而旁邊的人閱讀你的代碼(即使是你)具有最小的認知開銷。

+0

很好的例子。容易明白。 – 2014-01-31 14:35:34

0

似乎罰款給我(我使用Python的三元運算符很多),但這種風格的問題通常是非常主觀的。如果項目具有編碼風格文檔,則可能需要檢查該文檔。

1

我更喜歡第二個,因爲它更清晰地表達了你的意思:如果它不是null,你只想改變顏色。第一種方法並沒有這麼清楚。

2

使用三元運算符通常是一個敏感問題,以及其他編碼標準。它的使用可能最好由您的網站編碼標準來確定。

但是,在這種特定情況下,我肯定會推薦第二種方案;不僅更加清楚,而且在這裏完全不需要使用三元運算符。沒有必要重新分配給自己的messageColor,所以在這種特殊情況下,三元運算符的唯一功能是代碼混淆。

1

三元運營商經常被濫用,因爲他們生產的代碼看起來聰明而緊湊。

事實上,他們使代碼更不可讀,更容易出錯。 只要有可能,建議使用

if (<condition>) { 
    <action> ; 
} 

取而代之的是三元語法的更長的版本。

+0

不完全正確:三元運算符可以使代碼更具可讀性(並非總是,我同意) – 2009-11-29 12:43:46

2

三元運算符在C程序員中更爲常見。在C語言中,如果你避免了控制結構,你通常可以得到更好的流水線,因爲沒有分支預測會出錯。我懷疑你會在Java中看到任何性能差異,並且if-null-then-assign模式比三元模式更普遍。但是,如果您維護現有的代碼庫,通常最好保持與現有代碼一致。

如果你發現自己做了很多,你可以編寫一個defaultIfNull,firstNonNull或​​3210函數,這可能會使代碼更加簡潔。 Apache Commons Lang includes a defaultIfNull function.

某些語言包括||=運算符,這是這些語言中默認值的常用習慣用法。

+0

在C中使用條件運算符不會「避免控制結構」。看看你的編譯器輸出。 – 2009-11-29 18:50:59

+0

我看過我的編譯器輸出。 http://www.theeggeadventure.com/wikimedia/index.php/Ternary_Operator_in_C 原來,無論您使用三元結構還是if/then/else結構,gcc C編譯器都可以創建相同的程序集。 – brianegge 2009-11-29 22:08:44

+1

沒錯,編譯器可以爲if語句或條件運算符生成無分支代碼(如果可以的話)。如果它不能,那麼兩個語句都會生成分支。我指的是你的意思是「避免控制結構」與「使用條件運算符」是一樣的。 – 2009-11-30 18:26:03

1

就你而言,我更喜歡'經典'實現,因爲對我而言,理解起來更快,只有當人有首選顏色時纔會使用新顏色。

我有時用它在方法調用,如果我想避免的NPE,但我通常elimate那些醜陋的代碼片段,在接下來的重構之一;)

4

可讀性,便於理解等,都在同這種情況下(我的意思是,加油...)。我不喜歡第一個例子中的重複和明顯的自我分配;它會翻譯成類似於:

if (colour != null) {messageColour = colour;} 
    else {messageColour = messageColour;}; 

這是一個有點愚蠢。

我通常會在一行寫第二行,但這是個人花哨的問題。編碼樣式準則:

if (colour != null) {messageColour = colour;}; 

編輯(我現在比前8年之自以爲是)

既然你正在尋找最好的做法:

// Use default visibility by default, especially in examples. 
// Public needs a reason. 
class MessageFormat { 
    static final Color DEFAULT_COLOR = Color.RED; 

    // Strongly prefer final fields. 
    private final Color messageColor; 

    // Protect parameters and variables against abuse by other Java developers 
    MessageFormat (final Person person) { 
     // Use Optionals; null is a code smell 
     final Optional<Color> preferredColor = person.getPreferredColor(); 
     // Bask in the clarity of the message 
     this.messageColor = preferredColor.orElse(DEFAULT_COLOR); 
    } 
} 
+0

或即使(color!= null)messageColour = color; – 2009-11-29 13:35:19