Java 时髦地使用Return

Java 时髦地使用Return,java,coding-style,Java,Coding Style,假设我在if语句之间有很多代码。在它之前做一个快速的if-else检查是否更合适,如果失败,返回 或者创建包含大量代码的if语句,但不使用return 还是只是偏好的问题 因此,我的两个选择是: 如果某物{ 回来 } 其他的 //这里有很多代码 如果有什么{ //这里有很多代码 }从性能角度来看,您应该始终尽可能快地从函数返回,避免进行不必要的计算,如果愿意的话,还应该短路。因此,检查错误案例并快速返回将是更好的策略 编辑添加:同样,您应该首先检查最有可能被违反的情况,这也是构建条件时的合理建议

假设我在if语句之间有很多代码。在它之前做一个快速的if-else检查是否更合适,如果失败,返回

或者创建包含大量代码的if语句,但不使用return

还是只是偏好的问题

因此,我的两个选择是: 如果某物{ 回来 } 其他的 //这里有很多代码

如果有什么{ //这里有很多代码
}

从性能角度来看,您应该始终尽可能快地从函数返回,避免进行不必要的计算,如果愿意的话,还应该短路。因此,检查错误案例并快速返回将是更好的策略


编辑添加:同样,您应该首先检查最有可能被违反的情况,这也是构建条件时的合理建议| | |和&&checks

我认为这看起来更好:

func() {
   if(someCondition) {
      return;
   }

   if(otherCondition) {
      return;
   }

   //lots of code
}
除此之外:

func() {
   if(someCondition) {
      return;
   } else if(otherCondition) {
      return;
   } else {
      //lots of code
   }
}
或者这个:

func() {
   if(!someCondition) {
      if(!otherCondition) {
         //lots of code
      }
   }
}

它看起来更丑陋,条件更多,所以我通常使用第一种方法。

我更喜欢捷径。这与性能无关,因为现代计算机可以很快处理if-else,所以我们应该关注代码的可读性


然而,如果代码中有那么多if-else,您可能会重新考虑您的设计。重构可能是一个更好的选择。

可读性和性能不是必需的冲突约束,但当它们相互冲突时,我倾向于将可读性放在前面

为了提高可读性,我倾向于遵循以下规则

规则1。保持返回作为最后一行代码,无论中间出现什么。换句话说,不要因为不太确定if-else结构是否会在最终返回之前级联而在任何时候随意使用return语句

除了可能是最简单的方法之外,我喜欢这样的结构

MyType func() {
    MyType result ;
    if ( condition ) {
        result = result_1 ;
    } else {
        result = result_2 ;
    }
    return result ;
}
在一个据称更简单的

MyType func() {
    if ( condition ) {
        return result_1 ;
    } else {
        return result_2 ;
    }
}
在我看来,性能成本(如果有的话)可以忽略不计。然而,当放大时,我发现第一个编码模式更具可读性

规则2。不要通过疏散错误条件来启动逻辑,只是为了让它们远离障碍,解放你的思想。如果您的逻辑是经过深思熟虑的,那么这些检查将在逻辑中找到它们的位置,还可以查看许多在helpers中封装常规检查的好方法

我团队中的许多新生开始编写这样的代码

MyType func (ArgType arg1,...) {
    if ( arg1 == null ) {
        throw new Exception ( "hey dummy, we don't take null arg1) ;
        // or return null ;
        }
    if ( arg2 == null ) {
        // you got the picture...
        }
    // wow at last !!! all checks done
    // Combine args and return result...
}
我必须说,这已经是一个进步,只是把所有的条件都视为理所当然

我倾向于

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( try_to_compact_all_checks_here ) {
        // Combine args and return result...
    } else {
        // throw, log, nullify result etc
    }
    return result ;
}
如果条件try\u to\u compact\u这里的所有检查都不适合一行,我甚至有时更愿意让路,我将所有检查封装在一个私有函数中。即使只叫过一次

规则3。将if/else语句中的行数保持在合理的数量,基本上应该适合IDE中的一个屏幕。为此,有时可以提取一些逻辑并将其粘贴到私有函数中。没问题。所有现代IDE只需点击两次即可为您实现这一点

所以基本上前面的模板变成了

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( checks_here ) {
        // 1 to 20 lines max, 
        encapsulate lengthy logic in full fledged private methods.
    } else {
        // throw, log, nullify result etc
    }
    return result ;
}
规则4。内部的if应该总是有一个ELSE,而这个ELSE应该不同于外部的ELSE

说明:如果我最终

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( check_1 ) {
        if (check_2) {
           Do the real work
        } else {
           treat error condition
        }
    } else {
        same error condition as above
    }
    return result ;
}
那可能是因为我的支票分析不完整。这种情况经常发生。 我试着去

MyType func (ArgType arg1,...) {
    MyType result ;
    if ( check_1 && check_2) {
        Do the real work
    } else {
        same error condition as above
    }
    return result ;
}
就这些。
我发现,通过遵守这种约定,我可以用更复杂的业务逻辑(如ESB、Web服务等)处理大型Java项目,而性能成本非常低。

+1我尽量不在中间返回,因为这可能会让人困惑。我尽量保持我的回报,要么很早,要么很晚。如果我发现中间有很多回报,很可能我应该重新考虑我的设计。在这里,RooptQueNE99提出的情况下,没有性能上的差异。@ RLBBY正确-无论你是否使用早期回报,它应该是相同的性能。短路应采用任何一种方式。/同意Tom的意见。如果你回来了,你就不需要别的了。提前返回的一个好处是,在结束时覆盖返回条件时,您不必不断缩进一百万次。好的一点,我没有想到这一点。“我要处理的缩进少了一个。”格洛科德:阿门。这一点以及kgrad的答案所描述的效率是尽可能多地选择回报而非其他回报的主要原因,而不仅仅是一个。如果你有一些复杂的跳过逻辑,你很容易得到3或4。为了让你的代码更清晰,还有16个额外的空格需要使用。@Mac我希望在效率方面有所不同。正确完成后,无论是否将代码嵌套在ifs中,以及是否在末尾有一个返回,代码都将以相同的速度运行。我最多只能看到一条额外的分支指令。我更喜欢第二种方法,因为它很好地显示了if语句的独占性。我之所以不这样做,是因为如果else块是100行代码,那么您就可以毫无理由地获得额外的缩进。这使我们很难做到这一点
保持小的行宽。如果你有100多行的方法,那些If语句是你最不需要的问题。