简体   繁体   English

尝试捕获for循环

[英]try-catch in for loop

I have met something that I cannot explain to myself today. 我遇到了一些我今天无法向自己解释的事情。 It was a small task on an online resource to write a program that will be run on some tests. 编写在线程序可以在某些测试上运行,这是在线资源上的一项小任务。 Can you please explain me the difference between two methods and why one of them fails on some tests (I don't have them). 您能否解释一下两种方法之间的区别,以及为什么其中一种方法在某些测试中失败(我没有这些方法)?

The task is to write a static method that opens a connection and then tries 3 times to do some abstract stuff with this connection by calling its method. 该任务是编写一个静态方法来打开一个连接,然后尝试通过调用其方法3次来对该连接进行一些抽象的处理。 The problem is that any method you use can throw an exception (open connection and connection method). 问题是您使用的任何方法都可能引发异常(开放连接和连接方法)。 You must try to do the stuff exactly 3 times (if all attempts failed - throw an exception) and another condition is that every opened connection must be closed. 您必须尝试正确执行3次操作(如果所有尝试均失败-引发异常),并且另一个条件是必须关闭每个打开的连接。

The connection class called RobotConnection and it implements AutoCloseable . 名为RobotConnection的连接类,它实现AutoCloseable This class has method void moveRobotTo(int x, int y) (it is the "do stuff method" from the task). 此类具有方法void moveRobotTo(int x, int y) (这是任务中的“填充方法”)。 You can get instance of RobotConnection only by calling RobotConnectionManager.getConnection() . 您只能通过调用RobotConnectionManager.getConnection()来获取RobotConnection实例。 Methods of these classes can throw RobotConnectionException extends RuntimeException . 这些类的方法可以抛出RobotConnectionException extends RuntimeException

So the real question COMES HERE: 所以这里出现了真正的问题:

This code fails (no idea why, presumably infinite loop): 这段代码失败了(不知道为什么,大概是无限循环):

public static void moveRobot(RobotConnectionManager robotConnectionManager, int toX, int toY) {
    boolean success = false;
    for (int i = 0; !success && (i < 3); ++i) {
        try (RobotConnection connection = robotConnectionManager.getConnection()) {
            connection.moveRobotTo(toX, toY);
            success = true;
        }
    }
    if (!success) {
        throw new RobotConnectionException("3 attempts failed");
    }
}   

And this one was accepted as working (I cannot see the real difference =( ) 并且这个被认为是可行的(我看不出真正的区别=()

public static void moveRobot(RobotConnectionManager robotConnectionManager, int toX, int toY) {
    boolean success = false;
    for (int i = 0; !success && (i < 3); ++i) {
        try (RobotConnection connection = robotConnectionManager.getConnection()) {
            connection.moveRobotTo(toX, toY);
            success = true;
        } catch (RobotConnectionException e) {}
    }
    if (!success) {
        throw new RobotConnectionException("3 attempts failed");
    }
}

In your first method, you don't catch RobotConnectionException . 在第一种方法中,您不会捕获RobotConnectionException Consequently, it can fail at most once, rather than the required exactly 3 times . 因此,它最多只能失败一次,而不是要求的准确次数是3次

The difference is that in the first case, you say "open and clean up the connection, but I don't know how to deal with exceptions: let them propagate up the call chain to something which can handle it": 区别在于,在第一种情况下,您说“打开并清理连接,但我不知道如何处理异常:让它们沿调用链传播到可以处理的异常”:

try (RobotConnection connection = robotConnectionManager.getConnection()) {
  // ...
}

whereas in the second case, you say "open and clean up the connection, but if an exception occurs, I will deal with it myself; the action I will take is to do nothing": 而在第二种情况下,您说“打开并清理连接,但是如果发生异常,我将自己处理;将采取的措施是不执行任何操作”:

try (RobotConnection connection = robotConnectionManager.getConnection()) {
  // ...
} catch (RobotConnectionException e) {}

If a RobotConnectionException is thrown in the first code snippet, then it might come from inside the try statement. 如果在第一个代码段中引发了RobotConnectionException,则它可能来自try语句内部。 Since you do not catch it, you will not necessary make three attempts. 由于您没有抓住它,因此您无需进行三次尝试。

More information on java exceptions: http://docs.oracle.com/javase/tutorial/essential/exceptions/ 有关Java异常的更多信息: http : //docs.oracle.com/javase/tutorial/essential/exceptions/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM