Java if和if-else之间有什么明显的区别吗?
给出以下代码片段,有什么明显的区别吗Java if和if-else之间有什么明显的区别吗?,java,coding-style,maintainability,Java,Coding Style,Maintainability,给出以下代码片段,有什么明显的区别吗 public boolean foo(int input) { if(input > 10) { doStuff(); return true; } if(input == 0) { doOtherStuff(); return true; } return false; } vs 或者单出口原则在这段代码中会更好 public boolean foo(int i
public boolean foo(int input) {
if(input > 10) {
doStuff();
return true;
}
if(input == 0) {
doOtherStuff();
return true;
}
return false;
}
vs
或者单出口原则在这段代码中会更好
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
是否存在明显的性能差异?您是否觉得其中一个版本比其他版本更易于维护/可读 使用最能描述您意图的任何形式
但是,如果事情这么简单,就不要遵循单出口原则——这只会使它更加混乱。语义上-否。从性能上看,这取决于编译器,即它是否能够发现这两个条件不能同时为真。我敢打赌标准Sun编译器可以。是否使用单出口原则取决于口味。我个人讨厌它。第一个片段和第二个片段之间真的没有区别。然而,第三个代码片段效率很低。因为您等待将程序的控制权返回给调用方,直到方法中的最后一行代码,您浪费了处理能力/内存,而前两个代码段在确定其中一个条件为真时立即返回控制。对于第二个示例,您非常清楚地指出这两个条件是相互排斥的。
对于第一个ifs,则不太清楚,如果(不太可能)在两个ifs之间添加了对
输入的赋值,则逻辑将发生变化。
假设将来有人在第二个if之前添加input=0
。
当然,这不太可能发生,但是如果我们在这里讨论可维护性,if-else清楚地说存在相互排斥的条件,而一堆if不存在,它们之间不像if-else块那样相互依赖
编辑:现在我看到了,在这个特定的例子中,return子句强制相互排斥,但我们再次讨论的是可维护性和可读性
无论如何,关于性能,如果这是用Java编写的,那么你不应该关心几个if块的性能,如果它是嵌入在速度非常慢的硬件中的C,也许,但肯定不是用Java编写的。版本1和版本2可能比版本3快,但我认为性能差异很小。我宁愿关注可读性
就我个人而言,我永远不会使用版本2。在#1和#3之间,我会选择一个为所讨论的案例生成可读性最高的代码。我不喜欢我的方法中有很多退出点,因为这使得代码很难分析。但是,在某些情况下,当我们针对某些特殊情况立即退出时,流程会变得更清晰,并继续处理主要情况。想想这两个例子不相似时的情况:
public boolean foo(int input) {
if (input > 10) {
// doStuff();
return true;
}
System.out.println("do some other intermediary stuff");
if (input == 0) {
// doOtherStuff();
return true;
}
return false;
}
vs。
第一种方法可能更灵活,但两种公式在不同的情况下都有其用途
关于性能,我认为对于任何由理智的程序员编写的常规java应用程序来说,差异都很小:)。在您的例子中,第二个if只有在第一个if失败时才会被调用,所以这里不太重要,但是如果您的第一个if做了一些事情但没有返回,那么第二个if将被调用(这将永远是错误的)仍然会被测试,除非它是在一个else-if中
换句话说,在某些情况下,if-else-if和if-if之间的差异很重要,但这不是其中之一
示例:尝试此操作,然后在删除else后尝试。您将获得两种不同的输出:
int someNumber = 1;
if(someNumber < 5)
{
someNumber += 5;
Console.WriteLine("First call.");
}
else if(someNumber >= 5)
{
Console.WriteLine("Second call.");
}
int someNumber=1;
如果(某些数字<5)
{
someNumber+=5;
控制台。WriteLine(“第一次呼叫”);
}
else if(someNumber>=5)
{
控制台。WriteLine(“第二次呼叫”);
}
- 首先:
P.>有人最终出于某种奇怪的原因,当你不看时,会添加一些附加语句,使这个方法在某些奇怪的条件下失败,每个人(或最坏的,一个人)将花费4小时。看源代码并调试应用程序,最终发现中间有什么东西。
- 第二种肯定更好,它不仅可以防止这种情况,而且有助于清楚地表明,它不再是这样或那样
如果我们在一个最多10行的
If
中编写的所有代码,这其实并不重要,但不幸的是,事实并非如此,还有其他程序员出于某种原因认为If体的长度应该大于200行……无论如何
- 我不喜欢第三个,它迫使我寻找返回变量,而且更容易找到
return
关键字
关于速度性能,它们(几乎)是相同的。不要担心这一点。在上一个示例中,不要这样做:
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
但是这(注意Java的final的用法):
通过这样做,您可以清楚地表明您的意图,这是支持“按意图编程”的IDE的天赐之物(即使在部分AST上,也不需要“编译”来查看潜在错误,一个好的IDE可以实时检查不完整的源代码,并给您即时警告)
这样你就不会忘记初始化你的返回值。如果以后你决定你需要另一个条件,这是非常好的
自从我开始使用IntelliJ IDEA(很久以前的版本4左右)以来,我一直都在这样做,甚至更多,这让我避免了很多愚蠢的分心错误
有些人会争辩说,对于这样一个简单的例子来说,这是太多的代码了,但这完全没有抓住重点:重点是要明确意图,以便代码易于阅读,并且可以在以后轻松扩展,而不会意外忘记赋值返回,也不会意外忘记从后面的子句返回加上
否则,如果“简洁”是游戏的名称,那么我会写:
public boolean foo(int a) {
return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false;
}
doStuff和doOtherStuff都将返回true。你几乎肯定是不正确的-任何现代编译器都会将它们优化为相同的代码
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
public boolean foo(int input) {
final boolean toBeReturned; // no init here
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
} else {
toBeReturned = false;
}
return toBeReturned;
}
public boolean foo(int a) {
return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false;
}