鉴于以下代码片段,是否存在明显的差异?
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) {
if(input > 10) {
doStuff();
return true;
} else if(input == 0) {
doOtherStuff();
return true;
} else {
return false;
}
}
或者使用这段代码,单退出原则会更好......
public boolean foo(int input) {
boolean toBeReturned = false;
if(input > 10) {
doStuff();
toBeReturned = true;
} else if(input == 0) {
doOtherStuff();
toBeReturned = true;
}
return toBeReturned;
}
有任何明显的性能差异吗?你觉得一个人或多或少比其他人更易于维护/阅读吗?
答案 0 :(得分:10)
在第二个例子中,您非常清楚地说明两个条件是相互排斥的
对于第一个,它不是那么清楚,并且在(不太可能的)事件中,在两个ifs之间添加input
的赋值,逻辑将改变。
假设将来有人在第二个if之前添加input = 0
当然这不太可能发生,但是如果我们在这里谈论可维护性,如果 - 否则清楚地表明存在相互排斥的条件,而一堆ifs则没有,并且它们彼此之间没有那么依赖。 - 块。
编辑:现在我看到,在这个特定的例子中,return子句强制相互排他性,但同样,我们讨论的是可维护性和可读性。
无论如何,关于性能,如果用Java编码你不应该关心几个if块的性能,如果它是在一个非常慢的硬件中嵌入C,也许,但肯定不是用java。
答案 1 :(得分:4)
使用最能描述您意图的任何形式。
如果事情很简单,不要遵循单退出原则 - 这只会让它更加混乱。
答案 2 :(得分:4)
在第一个:
有人最终会因为一些奇怪的原因,当你不看时会添加一些补充声明,这会使这种方法在某些奇怪的条件下失败,每个人(或者最差的,一个人)将花费4小时。观察源代码并调试应用程序,最终发现中间有一些东西。第二个肯定更好,不仅可以防止这种情况,而且还有助于明确说明,这个或这个不再。
如果我们在if
内写的所有代码最多10行,这实际上并不重要,但遗憾的是并非如此,还有其他程序员因某种原因认为是if body应该是>无论如何,总共200行......
我不喜欢第三种,它强迫我查找返回变量,并且更容易找到return
关键字
关于速度表现,它们(几乎)相同。别担心。
答案 3 :(得分:1)
在上一个例子中,不要这样做:
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 ):
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;
}
通过这样做你可以清楚地表达你的意图,这是支持“按意图编程”的IDE的天赐之物(没有必要“编译”以查看潜在的错误,即使在部分AST上,一个好的IDE可以检查不完整的源代码实时并给你即时警告)。
这样您确定不要忘记初始化您的返回值。如果你以后决定毕竟还需要另一个条件,那就太棒了。
我一直这样做,甚至更多,因为我开始使用IntelliJ IDEA(很久以前的版本4左右),这给我带来了许多愚蠢的分心错误......
有些人会争辩说,对于这样一个简单的案例来说,这是太多的代码,但这完全忽略了这一点:关键是要明确意图,以便代码可以轻松读取,以后可以轻松扩展,而不会意外忘记分配 toBeReturned 并且不小心忘记从后面的句子中返回,你可以添加。
否则,如果“简洁”是游戏的名称,那么我会写:
public boolean foo(int a) {
return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false;
}
doStuff 和 doOtherStuff 都会返回true。
答案 4 :(得分:0)
语义 - 没有。性能方面,这取决于编译器,即它是否能够发现两个条件不能同时成立。我敢打赌标准的Sun编译器可以。是否使用单出口原则取决于口味。我个人讨厌它。
答案 5 :(得分:0)
版本#1和#2可能比#3快,但我认为性能差异很小。我宁愿专注于可读性。
就个人而言,我永远不会使用版本#2。在#1和#3之间,我会选择能够为相关案例生成最可读代码的那个。我不喜欢我的方法中的许多退出点,因为它使代码难以分析。但是,有些情况下,当我们立即退出某些特殊情况时,流程会变得更清晰,并继续主要案例。
答案 6 :(得分:0)
当两个例子不相似时,请考虑这种情况:
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;
}
public boolean foo(int input) {
if (input > 10) {
// doStuff();
return true;
}
//System.out.println("doing some intermediary stuff... doesn't work");
else if (input == 0) {
// doOtherStuff();
return true;
} else {
return false;
}
return false;
}
第一种方法可能更灵活,但两种公式都可以在不同情况下使用。
关于性能,我认为对于任何常规Java应用程序来说,差异都很小,需要由理智的程序员编写:)。
答案 7 :(得分:0)
在你的情况下第二个如果第一个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.");
}
答案 8 :(得分:-1)
在第一个和第二个片段之间,确实没有区别。然而,第三个片段效率很低。因为您等待将程序的控制权返回给调用者,直到方法中的最后一行代码,否则会浪费处理能力/内存,而前两个代码片段会在确定其中一个条件为真后立即返回控制。 / p>