我发现自己在使用下面的练习,但每次使用它,我内心的某些东西都会有点畏缩。基本上,这是一个先决条件的参数测试,以确定是否应该做实际的工作。
1 2 3 4 5 6 7
| public static void doSomething(List<String> things)
{
if(things == null || things.size() <= 0)
return;
//...snip... do actual work
} |
- 使用PMD、CheckStyle或FindBugs等工具获得第三个意见,然后搜索该意见。imho,只要按照您的编码标准考虑,这不是一个坏的实践。
- 您可以在这里阅读一个长线:programmers.stackexchange.com/questions/18454/&hellip;
- 这一定是复制品。尝试搜索答案。
- 如果它让你畏缩,它可能不是适合你的方法。
- 做了一个快速的搜索,但不知道该怎么说。谢谢你链接到线程,正是我要找的。
- 我认为您可以这样做,或者在调用函数之前检查参数,您的方法似乎更易于编码。
- "只返回一次"的论点再次出现。与Java无关,因为通常的做法是多次返回。
- 副本:stackoverflow.com/questions/36707/&hellip;
- 简单高效。那么你认为哪一个更简单?(早期回报)
尽早返回是一种良好的做法。这样就可以执行和评估最少数量的代码。
不能运行的代码不能出错。
此外,它使函数更易于阅读,因为您不必处理所有不再适用的情况。
比较以下代码
1 2 3 4 5 6 7 8 9
| private Date someMethod (Boolean test ) {
Date result ;
if (null == test ) {
result = null
} else {
result = test ? something : other ;
}
return result ;
} |
VS
1 2 3 4 5 6 7
| private Date someMethod (Boolean test ) {
if (null == test ) {
return null
}
return test ? something : other ;
} |
第二个比较短,不需要else,也不需要temp变量。
注意,在Java中,EDCOX1×1语句立即退出函数;在其他语言(例如Pascal)中,几乎等效的代码EDOCX1 OR 6不返回。由于这个事实,习惯上在Java方法的许多点返回。调用这个EDCOX1×7是忽略了那个特定的火车早就在Java中离开了站点的事实。
如果您无论如何都要在函数的多个点上退出一个函数,最好尽早退出
- 这是有道理的。我不知道某些语言在返回时可能不会退出函数。这为一些开发人员而不是其他人将其视为"坏做法"的原因提供了新的线索。
- 第一个示例实际上很臭,但是由于您编写它的方式,如果您编写的代码正确,那么它与第二个示例一样可读,并且更容易遵循流程:private date somemethod(boolean test)date result=null;if(test!=空)结果=测试?某物:其他;返回结果;
- - 1。不运行的代码肯定有错误。如果将我的存款添加到银行的代码没有运行,这是一个错误。至于实际问题,我同意提前归还,只是不是因为你的原因。
这是一个风格和个人喜好的问题。没什么问题。
据我所知-不。
为了便于调试,子例程、方法或函数中应该只有一个返回/退出点。
使用这种方法,您的程序可能会变得更长、更不可读,但是在调试期间,您可以在出口处放置一个断点,并始终看到返回的内容的状态。例如,您可以记录所有局部变量的状态—这对于故障排除可能非常有帮助。
看起来有两个"学校"——一个说"尽早返回",另一个说"一个程序中应该只有一个返回/退出点"。
我是第一个的支持者,尽管在实践中有时会跟随第二个,只是为了节省时间。
另外,不要忘记例外。通常情况下,您必须尽早从方法返回这一事实意味着您处于一个特殊的情况中。在您的示例中,我认为抛出异常更合适。
- 所以你想牺牲可读性来进行调试?另外,如果抛出一个异常,它将扰乱单个调试断点理论,因为异常只是另一个返回路径。
- @正如我已经说过的,这里没有办法选择一种通用的方法,这是一种权衡,不管你选择什么。返回-对于正常执行流,异常情况例外。除了例外,您总是可以看到堆栈跟踪。单一的返回点可以让您找到逻辑错误,而不是技术错误。
这个问题没有正确的答案,这是一个品味问题。
在上面的具体示例中,可能有更好的方法来强制执行前置条件,但我认为多个早期返回的一般模式类似于功能编程中的保护。
我个人对这种风格没有异议——我认为它可以产生更干净的代码。试图扭曲所有东西以获得一个单一的出口点可以增加冗长和降低可读性。
没有什么本质上的问题,但如果它让你畏缩,你可以扔一个IllegalArgumentException。在某些情况下,这更准确。但是,当您调用doSomething时,它可能会导致一系列代码出现这种情况:
- 你为什么要把例外扔得到处都是?
- @在大多数情况下我不会这样做,但在提前归还没有意义的情况下,例外可能更有意义。
- @RaptorTech97:+1表示在盒子外思考,并提到抛出一个异常,-1表示半建议抓住它,什么都不做。就像在呼叫前检查它是否无效一样简单。
PMD似乎是这样认为的,你应该让你的方法一直运行到最后,但是,为了某些快速的健全性检查,我仍然使用过早的return语句。
它确实会稍微降低方法的可读性,但在某些情况下,它可能比添加另一个if语句或其他方法更好,以便在所有情况下运行该方法。
这是很好的做法。所以继续努力吧。
- 你在哪里读到的?这是一个很好的练习?
- @Ashburlaczenko,一个人必须读一些东西才能认为这是一种良好的实践吗?
- 如果下一步没有什么可做的话,最好退出方法。
- @维沙伊德,那是个谎言/错误。想想代码维护,伙计。
- @卢卡斯,读/听/学任何东西。我的观点是,如果你同意辩论的一方,你应该用证据来支持你的事实。
如果函数很长(比如20行或更多行),那么最好在开始时返回很少的错误条件,这样在读取函数的其余部分时,代码阅读器就可以专注于逻辑。如果函数很小(比如5行或更少),那么开头的返回语句可能会分散读者的注意力。
因此,决策应该主要基于函数是否变得更可读或更不可读。
如果您想避免方法中的"返回":也许您可以使用自己的异常子类,并在方法的调用中处理它?
例如:
1 2 3 4 5 6
| public static void doSomething(List<String> things) throws MyExceptionIfThingsIsEmpty {
if(things == null || things.size() <= 0)
throw new MyExceptionIfThingsIsEmpty(1,"Error, the list is empty !");
//...snip... do actual work
} |
编辑:如果不想使用"return"语句,可以在if()中执行相反的操作:
1 2
| if(things != null && things.size() > 0)
// do your things |
- 这将是一个"过度复杂"的imho,因为现在他必须担心捕获异常;而且他从未声明他真的关心知道事件发生了。
- 抛出异常是另一个返回路径,因此仍然有多个返回
没有什么问题。就个人而言,我将使用else语句来执行函数的其余部分,并让它自然返回。
- 没有自然的回报。你必须有一个明确的return声明。
Java好的实践表明,尽可能经常地,返回语句应该是唯一的,并且在方法的末尾写入。要控制返回的内容,请使用变量。但是,对于从void方法返回,就像您使用的示例一样,我将执行签入,中间方法仅用于此目的。无论如何,不要把这个问题看得太严重了——像continue这样的关键字不应该根据Java好的实践来使用,但是它们在你的范围内。
- 这个所谓的"Java好实践"在哪里被记录?
- java.dzone.com/articles/common-code-violations-java stackoverflow.com/questions/884429/&hellip;programmers.stackexchange.com/questions/118703/&hellip;
- 我读到了完全相反的观点。
- @Alexkreutznaer首先,考虑到这样的规则,即首选问题是"可以回答的问题",而不是讨论,而且这个问题是重复的(以这个为例,我确信它不是唯一的一个),如果你真的在寻找一个投反对票的人,就去和那个问我,而不是我的人一起做,因为我已经当被问到时,只有一个提供链接,当有其他链接时,只有一行,没有引用,甚至被否决。我看孩子的照片,投反对票让我恶心。
- @乔治·安东尼奥·D&237;阿兹·贝尼托,我不记得我曾经投过谁的票。你的陈述很可疑。没有一致意见认为哪种方法更好。拜托,当有人反对你,你不认识我的时候,不要那么敏感,当我第一次反对你的时候,你就开始谈论"投反对票"。
- 据记录,是我投了反对票。我投了反对票,因为你声称一个事实而没有引证。
- Hanletesca&241;o没有人,包括我在内,给出了一个强有力的、明确的理由来支持他们的回答。所以我的和几乎所有的都是相反的,这并不是错误的原因。事实上,我认为最坚固的那个(特里斯坦2468的那个)是基于PMD的,像我一样思考。@很抱歉,我看到了投反对票,你的评论和误会。然而,我仍然反对投反对票的约翰,&191;请你解释一下,是什么使我的答案比其他大多数答案更不有用?
- @Jorge Antonio D&237;az Benito如果你用这样的词:"…那是一个谎言/错误"或"你真的在找一个投反对票的人",当你和一个完全陌生的人交谈时,准备好了的人会投反对票给你。你可能是个年轻人。放松点。让我投赞成票,只是让你知道这里没有人反对你。
- @顺便说一句,我和你的观点完全一样。方法/函数/子例程中应该只有一个出口点。
- Alexkreutznaer这个地方不是为了追求名誉,或者至少不是为了我。我不明白为什么@johan把我的答案标记为无效。如果他能给我一个解释,我会努力改进我未来的答案,这样它们就不会像这样无用了。我用以证明我所有的赞成票都是正当的,并解释为什么我不同意一个答案/认为一个问题/答案应该被否决。
- @Jorgeantoniod&237;az Benito I投了反对票,因为你把答案说成事实,而没有列出参考。就我个人而言,我想看看最佳实践的参考资料。我一直喜欢阅读关于编码风格/编码建议的文章,但你的答案中没有这方面的内容。
- +1解释投票否决的原因。
- 从您自己的链接stackexchange引用"sese经常使代码更加复杂。所以它是一种恐龙(除了C)不适合今天的大多数语言。它没有帮助代码的可理解性,反而阻碍了代码的可理解性。"
- @Stevekuo方法不应该太长。在这种情况下,是的,它把事情搞砸了。如果方法很长,可能意味着代码粒度有问题。