2009-11-29 32 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