Java if与try/catch 开销?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (146)

Java中是否有使用try / catch块的开销,而不是if块(假设所附代码不是这样请求的)?

例如,对于字符串采取以下两个“安全修剪”方法的简单实现:

public String tryTrim(String raw) {
    try {
        return raw.trim();
    } catch (Exception e) {
    }
    return null;
}

public String ifTrim(String raw) {
    if (raw == null) {
        return null;
    }
    return raw.trim();
}

如果raw输入很少null,这两种方法之间是否存在性能差异

此外,使用这种方法来简化代码布局是否是一种很好的编程模式tryTrim(),特别是当通过将代码封装在一个try / catch块中可以避免许多检查罕见错误条件时?

例如,通常情况下,有一种方法可以在接近开始时N parameters使用M <= N它们,如果任何这样的参数是“无效的”(例如,空字符串或空字符串),并且不影响其余部分码。

在这种情况下,k * M 如果块(其中k是每个参数的平均检查次数,例如k = 2对于空字符串或空字符串),不必写try / catch块会显着缩短代码,并且可以使用1-2行注释明确地注意到“非常规”的逻辑。

这种模式也会加速该方法,尤其是在错误情况很少发生的情况下,并且在不影响程序安全性的情况下这样做(假设错误条件是“正常”的,例如在字符串处理方法中空值或空值是可以接受的,虽然很少在场)。

提问于
用户回答回答于

我知道你问的是性能开销,但你真的不应该使用try/ catchif互换。

try/ catch是指那些出于您的控制而不是正常程序流程出错的事情。例如,试图写入文件并且文件系统已满?通常应使用try/ 处理这种情况catch

if报表应该是正常的流程和普通的错误检查。那么,例如,用户无法填充所需的输入字段?使用if该,不try/ catch

在我看来,您的示例代码强烈表明,正确的方法是if声明而不是try/ catch

为了回答你的问题,我会推测,一个try/ catch一个通常会有更多的开销if。要知道肯定,得到一个Java分析器,并找出你关心的特定代码。答案可能因情况而异。

用户回答回答于

我认为还有几点是有益的:

  • 使用try / catch对于非例外的控制流是不好的风格(在Java中)。(关于“非例外”意味着什么,经常会有争论...但那是另一个话题。)
  • 其风格不好的部分原因是try / catch是数量级比常规控制流语句更昂贵。实际的差异取决于程序和平台,但我预计它的成本会高出1000倍或更多。除其他外,创造异常对象捕获堆栈跟踪,查找和复制堆栈上每个帧的信息。堆栈越深,需要复制的越多。
  • 其风格不好的另一个原因是代码很难读懂。

1-在最近版本的Java 7中,JIT可以优化异常处理,从而在某些情况下大大减少管理费用。但是,默认情况下不启用这些优化。

There are also issues with the way that you've written the example:

  • 抓到Exception is very bad practice, because there is a chance that you will catch other unchecked exceptions by accident. For instance, if you did that around a call to raw.substring(1)你也会发现潜在的StringIndexOutOfBoundsExceptionS...和藏虫子。
  • 你的例子试图做的是(可能)在处理null弦乐。作为一般原则,您应该尽量减少使用null字符串,并试图限制其(有意)传播。在可能的情况下,使用空字符串代替null意思是“没有价值”。当你有一个案子的时候需要通过或返回nullString,在您的方法javadocs中清楚地记录它。如果使用null当他们不应该...那是个虫子。让它抛出一个异常。不要试图通过返回(在本例中)来弥补错误null...

后续

我的问题更笼统,不只是针对空值。

...而且我的回答中的大部分要点都不是关于空值的!

但是,请记住,在许多情况下,您希望允许偶尔出现的空值,或任何其他可能产生异常的值,而忽略它们。例如,当从某个地方读取键/对值并将它们传递给类似于上面的trimm()的方法时,情况就是如此。

是的,在某些情况下null价值是预期的,你需要处理它们。

但我会说tryTrim()做(通常)是错误的处理方法。null...。比较这三段代码:

// Version 1
String param = httpRequest.getParameter("foo");
String trimmed = tryTrim(param);
if (trimmed == null) {
    // deal with case of 'foo' parameter absent
} else {
    // deal with case of 'foo' parameter present
}

// Version 2
String param = httpRequest.getParameter("foo");
if (param == null) {
    // deal with case of 'foo' parameter absent
} else {
    String trimmed = param.trim();
    // deal with case of 'foo' parameter present
}

// Version 3
String param = httpRequest.getParameter("foo");
if (param == null) {
    // treat missing and empty parameters the same
    param = "";
}
String trimmed = param.trim();

最终你必须处理好null与常规字符串不同,它是通常一个好主意,尽快这样做。越远越null被允许从其原点传播,程序员就越有可能忘却那...null值是一种可能性,并编写假设为非空值的bug代码。忘记HTTP请求参数可能丢失(即param == null)是发生这种情况的典型案例。

我不是说tryTrim()本质上是不好的。但事实上,程序员认为需要这样的编写方法可能指示低于理想的空处理。

扫码关注云+社区

领取腾讯云代金券