关于Java:不必要的”else”语句

Unnecessary 'else' statement

本问题已经有最佳答案,请猛点这里访问。

如您所知,在Eclipse中,您可以打开"不必要的"else"语句"检查,该检查将触发if-then-else并提前返回。根据我的经验,在使用这种声明时,有两种最可能的情况:

1)预检查:

1
2
3
4
if (!validate(arg1)) {
    return false;
}
doLotOfStuff();

2)事后检查:

1
2
3
4
5
6
doLotOfStuff();
if (condition) {
    return foo;
} else {
    return bar;
}

在第二种情况下,如果触发器打开,Eclipse将建议您将代码更改为:

1
2
3
4
5
doLotOfStuff();
if (condition) {
    return foo;
}
return bar;

但是,我认为使用else语句返回更具可读性,因为它类似于业务逻辑的直接映射。所以我很好奇,如果这种"不必要的"else"语句的代码约定很普遍,或者用else语句的代码更可取?


通常,我希望代码的结构遵循底层"业务"逻辑的结构。在这种情况下,我的方法将取决于condition代表什么。例如,如果它是一个错误检查,通常不会被点击,但偶尔会被使用,那么第二种形式的不对称性与逻辑的不对称性相匹配。

1
2
3
4
5
doLotOfStuff();
if (condition) {
    return foo;
}
return bar;

但是,如果这两种可能性都是合理的,而且只是它们之间的一种选择,我会允许代码的结构显示这种对称性。

1
2
3
4
5
6
doLotOfStuff();
if (condition) {
    return foo;
} else {
    return bar;
}

代码是供程序员阅读的,而不是编译器。


曾经有人认为(可能还有人认为)函数应该有一个入口点(很容易,但在考虑汇编语言时是相关的)和一个出口点。

从调试的角度来看,一个退出点是很好的(就像你可以在一条线上放一个手表/手表,并知道你会经历它),但可能会导致一些可怕的嵌套,因此经常会比不可读性更容易获胜。哪个产生最少的嵌套、最少的代码行和最可读的最终结果?最终,这比其他任何事情都重要得多。

就其价值而言,最后一个可以更好地表示为:

1
return condition ? foo : bar;

假设condition不是很长。

不要过分关注所谓的代码"纯度"。这是不相干的干扰。使事物可读,并且通常保持一致。


好的,一些著名的Java专家争辩说,一个人应该总是尽量减少事情的范围,这也是我的观点。

我在大学的老师总是让我苦恼,我必须写一些以前有人发的这样的东西:

1
2
3
4
5
6
7
8
String result = null;
doLotOfStuff();
if (condition) {
    result = foo;
} else {
    result = bar;
}
return result;

变量结果现在有一个很大的范围。此外,如果您在这里做得更多一些,比如说您有另一个for循环,那么对于很多嵌套来说,这会变得非常不可读。

我觉得这样好多了:

1
2
doLotOfStuff();
return condition ? foo : bar;

这是直截了当的。我马上就知道发生了什么,没有检查大括号。

我觉得很好

  • 最小化范围
  • 最小化缩进(即避免使用大括号)
  • 最小化方法长度

"多余的else语句"警告对此有所帮助。


我找到这个表格了

1
2
3
4
5
doLotOfStuff();
if (condition) {
    return foo;
}
return bar;

要比使用其他代码的代码更易读,如果您像Fowler的重构一样将其看作一个保护语句,那么它的代码更少,而且更直观。

关于多个返回点的问题。


嗯,我认为使用多重返回是不可读的。

我喜欢代码为:

1
2
3
4
5
6
7
8
9
10
String result = null;

doLotOfStuff();
if (condition) {
    result = foo;
} else {
    result = bar;
}

return result;

多重回报很难理解。但对你来说,我更喜欢后验

1
2
3
4
5
6
doLotOfStuff();
if (condition) {
    return foo;
} else {
    return bar;
}


我知道,如果没有IDE为我检查这个,我几乎总是使用不必要的else语句。通常我发现它一开始读起来更好,但当它被指出时,通常会删除它,因为我可以看到这是不必要的事实,然后它会让我抓狂…


在我看来,Eclipse检查不是很有用。您应该做什么取决于您的程序上下文。else子句是可选的(不管是这个还是那个),而陷入返回(没有其他子句)是更合适的,因为您有许多条件可能是真的,而fallthrough更像是一个默认反应,您不经常调用。因此,在代码中同时使用这两种方法来传递意义,因此检查是否存在是没有用的。


叫我坏孩子,但我通常会:

1
2
doLotOfStuff();
return condition ? foo : bar;

单返回语句,可读性强。


如果跟踪以下代码,我会注意到第一个if块是一个异常的代码块。但是,如果我在其中添加一个"else",我可能会认为这两个都是可操作的代码块。

另外,对于主操作块,可能有一些嵌套的块。我更喜欢最小化嵌套级别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public String myMethod(input) {
    if (!validate(input)) {
        return"invalid input";
    }

    operation1();
    if (someCondition) {
        operation2();
    } else {
        operation3();
    }
    operation4();
    operation5();
    return operation6();
}

一些程序员声称,处于函数中间的return是不好的做法。可能为了方便在函数条目处进行检查,正如在第一个示例中一样,这是可以接受的,但在其他情况下,我更喜欢将result变量设置为jerome response中的变量。