我有一个这样的循环:

for (int i = 0; i < max; i++) {
    String myString = ...;
    float myNum = Float.parseFloat(myString);
    myFloats[i] = myNum;
}

这是一个方法的主要内容,该方法的唯一目的是返回浮点数数组。我想让这个方法在出现错误时返回null,所以我把循环放在try…Catch block,像这样:

try {
    for (int i = 0; i < max; i++) {
        String myString = ...;
        float myNum = Float.parseFloat(myString);
        myFloats[i] = myNum;
    }
} catch (NumberFormatException ex) {
    return null;
}

但后来我也想到试一试……Catch块在循环中,像这样:

for (int i = 0; i < max; i++) {
    String myString = ...;
    try {
        float myNum = Float.parseFloat(myString);
    } catch (NumberFormatException ex) {
        return null;
    }
    myFloats[i] = myNum;
}

是否有任何理由,性能或其他方面,更喜欢其中一个?


编辑:共识似乎是,将循环放在try/catch中更干净,可能是在它自己的方法中。然而,关于哪个速度更快仍存在争议。有人能测试一下并给出一个统一的答案吗?


当前回答

我把0.02美元放进去。有时,您需要在稍后的代码中添加“finally”(因为谁会在第一次就写出完美的代码呢?)在这些情况下,将try/catch放在循环之外突然变得更有意义了。例如:

try {
    for(int i = 0; i < max; i++) {
        String myString = ...;
        float myNum = Float.parseFloat(myString);
        dbConnection.update("MY_FLOATS","INDEX",i,"VALUE",myNum);
    }
} catch (NumberFormatException ex) {
    return null;
} finally {
    dbConnection.release();  // Always release DB connection, even if transaction fails.
}

因为如果出现错误,您只希望释放一次数据库连接(或选择您最喜欢的其他资源类型……)。

其他回答

虽然性能可能是相同的,“看起来”更好的是非常主观的,但在功能上仍然有相当大的差异。举个例子:

Integer j = 0;
    try {
        while (true) {
            ++j;

            if (j == 20) { throw new Exception(); }
            if (j%4 == 0) { System.out.println(j); }
            if (j == 40) { break; }
        }
    } catch (Exception e) {
        System.out.println("in catch block");
    }

while循环位于try catch块内,变量'j'将递增到40,当j mod 4为零时输出,当j达到20时抛出异常。

在详细介绍之前,先来看另一个例子:

Integer i = 0;
    while (true) {
        try {
            ++i;

            if (i == 20) { throw new Exception(); }
            if (i%4 == 0) { System.out.println(i); }
            if (i == 40) { break; }

        } catch (Exception e) { System.out.println("in catch block"); }
    }

与上面的逻辑相同,唯一不同的是try/catch块现在在while循环中。

下面是输出(在try/catch中):

4
8
12 
16
in catch block

而另一个输出(try/catch in while):

4
8
12
16
in catch block
24
28
32
36
40

这里有很大的不同:

While in try/catch跳出循环

Try /catch in while保持循环活动

在你的例子中没有功能上的区别。我觉得你的第一个例子可读性更强。

As already mentioned, the performance is the same. However, user experience isn't necessarily identical. In the first case, you'll fail fast (i.e. after the first error), however if you put the try/catch block inside the loop, you can capture all the errors that would be created for a given call to the method. When parsing an array of values from strings where you expect some formatting errors, there are definitely cases where you'd like to be able to present all the errors to the user so that they don't need to try and fix them one by one.

如果这是一个全有或全无的失败,那么第一种格式是有意义的。如果希望能够处理/返回所有未失败的元素,则需要使用第二种形式。这些就是我选择方法的基本标准。就我个人而言,如果是孤注一掷,我不会使用第二种形式。

为try/catch设置一个特殊的堆栈框架会增加额外的开销,但是JVM可能能够检测到您正在返回并优化它。

根据迭代次数的不同,性能差异可能可以忽略不计。

然而,我同意其他人的观点,把它放在循环之外会让循环体看起来更干净。

如果您希望继续处理,而不是在存在无效数字时退出,那么您将希望代码位于循环中。