我是一名计算机科学专业的学生,所以我不知道那么多。
我最近和一位刚接受(java)软件开发人员工作的朋友谈话。他告诉我,在他的工作中有一个人在C ++方面很有经验,但不幸的是每次他用java编写代码时,他都会使用try-catch来控制程序的流程。据我的朋友说,这是一种错误的Java风格。这是真的?在C ++和Java之间使用try-catch(最终在java中)有什么不同(如果有的话)?
答案 0 :(得分:28)
使用try-catch来控制程序的流程在任何地方都是错误的...异常处理就是它所说的:处理异常的情况。
当然,对于每个规则,都有十几个必要偏差的反例,但一般而言:不要控制程序流程,但有例外。
当您预计在正常操作环境中抛出某些异常时,会使用异常来控制程序流,并根据这些异常做出逻辑决策。
例如,以伪代码控制程序流程:
try {
write update to file
} catch (IOException) {
write update to alternate file
}
在这种情况下,最好在盲目执行写操作之前实际测试路径存在。
我删除了权限检查说明,因为这是一个不好的例子
异常处理的良好用法:(再次伪代码)
try {
do stuff
} catch(OutOfMemoryException) {
fail gracefully (don't try and do something else to achieve the same result)
}
答案 1 :(得分:8)
我想说从程序架构的角度来看,Java和C ++中异常的目的是相同的。它们应该用于处理特殊情况,而不是直接正常的程序流程。
反对使用例外的最常见论点是它们很慢。像大多数基于代码速度的参数一样,现在几乎总是无关紧要,尤其是在正确使用异常时。
答案 2 :(得分:6)
我认为他所说的是他正在使用例外的非常规条件,如正常的循环终止。在大多数提供异常的语言中,程序员都认为这是禁忌,包括C ++。
这样做的原因是异常往往会拖累相当多的信息。在某些平台上,它们将整个callstack带到异常点,以便在一个很好的调试消息中显示它。如果你真正想要的是一个无条件的控制跳跃,这是非常昂贵的。
相反,您应该使用break
,return
或甚至(真正的捏合)goto
等语句。
答案 3 :(得分:4)
我希望C ++和Java世界在他们的观点中大致相似:
答案 4 :(得分:3)
try
/ catch
的唯一目的是流量控制。它旨在让我们摆脱任何循环,甚至超越调用者并达到更高级别的功能。
但是,它是为异常条件而设计的,例如使用空引用,除法溢出或文件I / O失败。这些错误会阻止程序继续运行并且必须处理。一般来说,它们很难预测或非常罕见。
当出现异常情况时,最好的做法是改变控制流程,以便尽可能多地抛出异常,以便找到愿意处理它的catch块。中间的任何方法都会被中止和解除,即使它没有代码来检查结果。
当人们抱怨使用try
/ catch
进行流量控制时,他们应该意味着它不是非特殊情况下的流量控制。如果你要做的就是退出循环,请使用break
或return
;不要抛出异常然后抓住它。这不是什么例外,也不是它们的好处。
答案 5 :(得分:2)
try-catch块用于在所有语言中执行相同的操作 - 例外是在出现问题时恢复的众多方法之一。在java中,以下两个语句是相同的:
if(x != null){
//do the normal thing
}
else{
//recover from the error
}
和
try{
//do the normal thing
}
catch(NullPointerException ex){
//recover
}
但是,出于多种原因,使用例外从来都不是好主意:
答案 6 :(得分:1)
他可能想要的是多种不执行一些代码的方法...而不是(在java中)
if (cond1) {
some_code();
if (cond2) {
some_more_code();
if (condN) {
ad_infinitum
}
}
}
这可以通过扔垃圾来“扁平化”......
try {
if (!cond1) throw new Throwable();
some_code();
if (!cond2) throw new Throwable();
some_more_code();
if (!condN) throw new Throwable();
ad_infinitum();
} catch (Throwable ignore) { }
问题是如果引发了一些真正的异常?我认为如果他想要缩进缩进,你的同事应该写的是这样的:
do {
if (!cond1) break;
some_code();
if (!cond2) break;
some_more_code();
if (!condN) break;
ad_infinitum();
} while (false);
因为do / while总是执行,所以我们可以使用break来逼近goto(只要它们都到达同一个地方)。
答案 7 :(得分:-2)
如果没有示例代码,您的问题就太模糊了。 C ++中没有finally
。
编辑通常,您不希望使用exceptions
作为控制流量的方法。 Exceptions
应该仅用于特殊(意外情况)情况。