关于编码风格:更好的Java方法语法?return的位置更靠前还是靠后呢?

Better Java method Syntax? Return early or late?

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

Duplicate: Should a function have only one return statement?

通常情况下,您可能会有一个方法来检查许多条件并返回一个状态(比如现在的布尔值)。最好定义一个标志,在方法期间设置它,然后在结束时返回它:

1
2
3
4
5
6
7
8
9
boolean validate(DomainObject o) {
  boolean valid = false;
  if (o.property == x) {
     valid = true;
  } else if (o.property2 == y) {
     valid = true;
  } ...
  return valid;
}

或者,在知道方法的结果后,简单地返回是否更好/更正确?

1
2
3
4
5
6
7
8
9
boolean validate(DomainObject o) {

  if (o.property == x) {
     return true;
  } else if (o.property2 == y) {
     return true;
  } ...
  return false;
}

现在很明显,可能有try/catch块和所有其他类型的条件,但是我认为这个概念是清楚的。意见?


如果这是一种方法,您将调用数千次,那么早期返回更好地实现[稍微]提高的性能。

如果没有,那么我更喜欢延迟返回,因为它提高了可读性。

记住,程序员通常花更多的时间阅读而不是编写代码,所以任何你能做的提高可读性的事情都会受到欢迎。


我喜欢早点回来,避免深窝。在这个方法的开头,这一点尤其正确:测试任何简单的东西,如果你能很早就这样做的话,就退出(或者抛出一个异常)。

如果它正好在一个方法的中间,那么它更像是一个判断调用。

请注意,我将立即重构您的示例以使用单个if

1
2
3
4
5
6
boolean validate(DomainObject o) {    
  if (o.property == x || o.property2 == y) {
     return true;
  } ...
  return false;
}

我知道这只是一个玩具示例,但我的观点是,始终值得寻找更多简化代码的方法:)


与大多数编码样式一样,这确实是一个优先事项,但许多人认为保护子句是一种最佳实践。


唯一一次我会说你肯定不应该早点返回是如果你不能很容易地在一个屏幕内看到每一个返回(无论标准是什么,为同一代码库工作的人),你至少应该添加注释,表明如果有早点返回,函数可以早点返回。

唯一一次我会说你肯定应该早点回来,如果你的代码看起来像…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
boolean valid = true;
if( condition1 ) {
   valid = false;
}
if( valid ) {
   ...
   if( condition2 ) {
      valid = false;
   }
}
if( valid ) {
   ...
   if( condition3 ) {
      valid = false;
   }
}
... (etc)

但是,如果你发现自己处于这些情况中的任何一种…您可能应该重构函数。


有两个因素相互影响。

第一个因素是易于调试。如果您立即返回(如第二个代码片段中所示),则有时很难调试大型函数,因为很难找到这些返回语句,特别是错误地将它们放在那里时。

第二个因素是易于实现。如果在函数开始时检查参数的基本正确性,并且在函数完成之前有一段很长的代码,那么可能需要将整个代码放入一个条件循环中。如果你不这样做,在某种程度上,这个论点可能会被用于一些长期的计算,浪费时间,因为它最终会被拒绝。

所以,答案可能是这样的:

1
2
3
4
If the function is small,
        save the return status in a variable and return at the end.
else
        return immediately.

如果例外情况不在图片的一部分,我宁愿在可以的时候立即返回。

很容易管理错误的标志变量,通常我反对标志变量。不返回也可能使维护人员认为可以做进一步的工作(如果方法很长)。


对我来说,这是一个没有正确答案的宗教战争主题。反对过早返回的论点基本上归结为这样一个事实,即只有一个函数可以退出的点可以减少通过代码的可能路径的数量,因此,至少在理论上,减少了出现错误的机会。我的个人风格是,在有意义的情况下提前返回,在有意义的情况下限制一个返回声明,我这样做。


对于这种情况,我更喜欢:

1
2
3
4
5
6
7
8
boolean validate (DomainObject o) {
    if (o.property == x ||
        o.property2 == y ||
        ...) {
          return true;
    } else {
          return false;
}

一般来说,我喜欢使用早期返回来处理错误条件,并在结束时返回计算结果。


老实说,我认为这取决于情况。我个人同时使用这两种方法,并根据哪种方法使代码更清晰易读。

如果您有大量嵌套的if语句(或任何其他控制结构),并且它可能会变得混乱,那么我将返回语句内部。

在这种情况下,不要太担心什么是"最佳实践",因为更重要的是代码清晰易懂。使用适合这种情况的东西。


就我个人而言,我更喜欢第二种方法。这对我来说是直截了当和清晰的,但我知道有些人在一个函数中必须只有一个返回。