Java:if-return-if-return 与 if-return-elseif-return
问了一个 不相关的问题,我有这样的代码:
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
// Check property values
}
我收到一条评论,声称这不是最佳的,并且它相反(如果我理解正确的话)应该这样做:
public boolean equals(Object obj)
{
if (this == obj)
return true;
else if (obj == null)
return false;
else if (getClass() != obj.getClass())
return false;
// Check property values
}
由于 return 语句,我真的不明白为什么它们中的任何一个应该比另一个更高效或更快。就我所知,给定某个对象,两种方法都必须执行相同数量的检查。由于存在 return 语句,因此任何额外的代码都不会运行。
我在这里错过了什么吗?有什么关系吗?是否有一些编译器优化或正在发生的事情或其他什么?
我知道这是微观优化,我很可能会坚持使用第一种方式,因为我认为所有 if 都位于同一位置时它看起来更干净。但我无能为力;我很好奇!
Asked an unrelated question where I had code like this:
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
// Check property values
}
I got a comment which claimed that this was not optimal, and that it instead (if I understood correctly) should do this:
public boolean equals(Object obj)
{
if (this == obj)
return true;
else if (obj == null)
return false;
else if (getClass() != obj.getClass())
return false;
// Check property values
}
Because of the return statements, I can't really see why any of them should be more efficient or faster than the other. Given a certain object, both methods would have to do an equal number of checks as far as I can see. And because of the return statements, no extra code would run in any of them.
Am I missing something here? Is there something to it? Are there some compiler optimizations or something going on or whatever?
I know this is micro optimization and I will most likely stick with the first either way, since I think it looks cleaner with all the ifs on the same position. But I can't help it; I'm curious!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这两种情况生成的字节码是相同的,因此这纯粹是风格问题。
我生成了两个方法
e1
和e2
,并且都生成了此字节代码(使用javap -v
读取):我遗漏了后面放置的代码使其编译。
The generated byte code is identical for those two cases, so it's purely a matter of style.
I produced two methods
e1
ande2
and both produced this byte code (read usingjavap -v
):I left out the code I put after that to make it compile.
两者都不比另一者更有效率。编译器可以很容易地看出两者是相同的,事实上 Suns/Oracles
javac
为这两个方法生成相同的字节码。这是一个
IfTest
类:我用
javac
编译它,反汇编如下:
也就是说,我建议使用第一个版本(不带
else
)。有些人可能会认为它与其他部分相比更干净,但我认为相反。 包括else
表明程序员没有意识到这是不必要的。Neither one is more efficient than the other. The compiler can easily see that the two are identical, and in fact Suns/Oracles
javac
produces identical bytecode for the two methods.Here is an
IfTest
class:I compiled it with
javac
and the disassembly is as follows:That is, I would recommend using the first version (without the
else
). Some people may argue that it's cleaner with the else parts, but I would argue the opposite. Including theelse
indicates that the programmer didn't realize that it was unnecessary.我认为没有任何实际理由将其中一种实现替换为另一种实现 - 在任何方向上。
如果您想避免在一个方法中使用多个 return 语句,那么第二个示例是有意义的 - 有些人更喜欢这种编码方式。 那么我们需要 if-else if 结构:
I don't see any practical reason to replace one of those implementations with the other one - in any direction.
The second example would make sense if you wanted to avoid multiple return statements in one method - some people prefer that way of coding. Then we need the if-else if constructs:
这样想吧。当执行 return 语句时,控制权离开方法,因此 else 并不会真正添加任何值,除非您想争辩说它增加了可读性(我真的不认为它会这样做,但其他人可能不同意)。
因此,当您遇到以下情况时:
将
else
添加到第二个if
中实际上没有任何价值。事实上,我在编写 C# 代码时使用了一个名为 Resharper 的工具,它实际上会标记
else
在这些情况下是无用的代码。所以我认为一般来说,最好将它们排除在外。正如 Joachim 已经提到的,编译器无论如何都会优化它们。Think of it this way. When a return statement is executed, control leaves the method, so the
else
doesn't really add any value, unless you want to argue that it adds readability (which I don't really think it does, but others may disagree).So when you have:
There's not really any value in adding an
else
to the secondif
.In fact, I use a tool when writing C# code called Resharper, and it will actually mark the
else
as useless code in these situations. So I think that generally, it's better to leave them out. And as Joachim already mentioned, the compiler optimizes them away anyway.我认为这段代码可以稍微改进一下(请注意,它非常可读):
instanceof
运算符相当于这两个组合,并且可能更快 - 代码更少,并且没有方法调用:但是我知道什么......我懒得分析字节码(以前从未这样做过)。 :-p
I think this code can be improved a little (mind you, it is very readable):
The
instanceof
operator is equivalent to both of those combined and is probably faster - less code, and no method invocations:But what do I know.... I'm too lazy to analyze the byte code (having never done it before). :-p