关于try / catch块中变量范围的问题

时间:2010-09-16 17:52:59

标签: java try-catch

我有一段可能会或可能不会失败的代码,我想在放弃之前尝试X次。当它失败时,它抛出一个特定的异常,所以我认为这样的东西会起作用:

    int retries = 0;
    while (retries < MAX_RETRIES) {
        failedFlag = false;
        try {
            //...do some stuff...
            logger.info("After commit...");
            if (!failedFlag) {
                logger.info("Failed flag is false, so breaking out.");
                break;
            }
        } catch (MyException e) {
            retries++;
            failedFlag = true;
            long sleepMillis = MILLIS_TO_SLEEP * retries;
            logger.warn("Caught a failure");
            logger.warn("Will sleep for " + sleepMillis + "msec and then try again.");
            try {
                Thread.sleep(sleepMillis);
                logger.info("Done sleeping...");
                logger.info("Failed flag is " + (failedFlag ? "true" : "false"));
            } catch (InterruptedException e1) {
                logger.warn("Caught interrupted exception while sleeping.  Terminate.");
                transaction.rollback();
                return;
            }
        }
    }

我遇到的问题是在第一个catch块中对failedFlag所做的更改似乎没有持续。失败后,线程会休眠,但当它被唤醒并重新进入try块时,failedFlag会恢复为false?我得到以下日志行:

2010-09-16 17:09:48,448 WARN  [pool-1-thread-1] synchronizer.FlightCreativeSynchronizer - Will sleep for 60000msec and then try again.
...
2010-09-16 17:10:48,449 INFO  [pool-1-thread-1] synchronizer.FlightCreativeSynchronizer - Done sleeping...
2010-09-16 17:10:48,450 INFO  [pool-1-thread-1] synchronizer.FlightCreativeSynchronizer - Failed flag is true
2010-09-16 17:10:48,453 INFO  [pool-1-thread-1] synchronizer.FlightCreativeSynchronizer - After commit...
2010-09-16 17:10:48,453 INFO  [pool-1-thread-1] synchronizer.FlightCreativeSynchronizer - Failed flag is false, so breaking out.

有点在这里感到困惑......局部变量是否不受catch块中所做更改的影响?

5 个答案:

答案 0 :(得分:4)

您正在while循环的顶部将failedFlag设置为false。

答案 1 :(得分:2)

如果将失败标志置于while循环上方,则它将在循环外部具有范围。目前,使用您拥有的作用域,每次循环重新启动时都会重新定义该标志。

希望有所帮助。


编辑:为了更清楚,你应该改变

int retries = 0;
while (retries < MAX_RETRIES) {
    failedFlag = false;

int retries = 0;
failedFlag = false;
while (retries < MAX_RETRIES) {

答案 2 :(得分:0)

在while循环中执行的第一件事是将标志设置为false。因此,当发生异常时,将标志设置为true,稍微休眠一下,然后将标志设置为false并重试。不可思议的是,在重试之后仍然是假的......

答案 3 :(得分:0)

每次启动循环时都会设置failedFlag,因此当您输入try块时它将始终具有false值。您可能希望在while循环之外初始化它。

答案 4 :(得分:0)

是的,局部变量会受到catch块变化的影响。

显然failedFlag回到假(在下一次迭代),因为它打印出“失败的标志是假的,所以爆发。”