12

这是可接受的编码实践吗?

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;
}
4

8 回答 8

25

?: 运算符的使用应仅限于使代码更具可读性。一个经典的例子:

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 的值。我认为应该避免这种情况,因为它可能会使人们感到困惑。

最重要的是保持一致,以便下一个阅读您的代码的人(即使是您)具有最小的认知开销。

于 2009-11-29T10:45:08.587 回答
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);
    }
}
于 2009-11-29T11:39:55.177 回答
2

使用三元运算符以及其他编码标准通常是一个敏感问题。它的使用可能最好由您站点的编码标准来确定。

但是,在这种特定情况下,我肯定会推荐第二种选择;不仅更清楚,而且这里完全不需要使用三元运算符。无需将 messageColor 重新分配给自身,因此在这种特殊情况下三元运算符的唯一功能是代码混淆。

于 2009-11-29T10:37:08.503 回答
2

三元运算符在 C 程序员中更为常见。在 C 中,如果您避免使用控制结构,您通常可以获得更好的流水线,因为没有分支预测会出错。我怀疑你会在 Java 中看到任何性能差异,并且 if-null-then-assign 模式比三元模式更常见。但是,如果您要维护现有代码库,通常最好与现有代码保持一致。

如果您发现自己经常这样做,您可以编写一个defaultIfNull,firstNonNullcoalesce函数,这可以使代码更加简洁。 Apache Commons Lang 包含一个defaultIfNull函数。

某些语言包含一个||=运算符,这是在这些语言中默认值的常用习惯用法。

于 2009-11-29T10:42:01.950 回答
1

我更喜欢第二种,因为它更清楚地表达了你的意思:你只想改变颜色,如果它不为空。第一种方法并没有说明这一点。

于 2009-11-29T10:33:47.443 回答
1

三元运算符经常被滥用,因为它们生成的代码看起来既聪明又紧凑。

事实上,它们使代码的可读性降低并且更容易出错。建议尽可能使用较长版本的

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

而不是三元语法。

于 2009-11-29T10:38:20.320 回答
1

在您的情况下,我更喜欢“经典”实现,因为对我来说,它可以更快地理解,如果该人有首选颜色,您只想使用新颜色。

如果我想避免 NPE,我有时会在方法调用中使用它,但我通常会在下一次重构中删除那些丑陋的代码;)

于 2009-11-29T11:25:41.237 回答
0

对我来说似乎很好(我经常使用 Python 的三元运算符),但这种风格问题通常是非常主观的。如果项目有编码风格文档,您可能需要检查一下。

于 2009-11-29T10:33:24.370 回答