尝试Catch Final - final变量

时间:2015-09-23 09:11:35

标签: java null try-catch

我目前面临着我的代码问题,我无法弄清楚为什么这句话正在评估。这是我第一次使用finally块,因此可能存在一些我尚未理解的基本行为。

此方法的作用是从api获取json文档并将所述文档存储为this.thisPage。然后另一个方法sliceItem将结果字段拆分为json对象数组。

每当API返回一个包含错误字段的json时(例如,String字段存储为int,或int作为double等),就会抛出MalformedJsonException。尝试10次(由failsafeget处理),如果失败10次,则抛出MalformedJsonException(RuntimeException)。在这种情况下我想要slicePage做的是获取下一页而不是继续这个页面。为了简化这一点 - 每个页面有100个条目;如果偏移量3500被破坏,我们希望得到偏移量3600。

我目前面临的问题是resp总是在最后一个块中评估为null。我无法理解为什么会这样,因为try块可以返回null以外的东西(JSONObject类型)。

非常感谢任何帮助,如果您需要更多信息/代码,我愿意提供。

public synchronized void slicePage(){
    JSONObject resp=null; // otherwise java complains that not initialised
    ApiClient apiClient = new ApiClient();
    RestEndPoint pageUrl;
    while (true) {
        pageUrl = getNextPageEndPoint();
        if(pageUrl == null) {
            throw new IllegalStateException("We have reached the end and the code isn't designed to handle the end here"); // we have reached the end
        }
        currentPageNumber++;
        try {
            resp = apiClient.failSafeGet(pageUrl, getRetryCount());
            break;
        }
        catch (MalformedJsonException e) {
            logger.info(String.format("The json was still broken after %d retries. Skipping this page and notifying listeners", getRetryCount()));
            for (Consumer<Integer> consumer: onSkipListenerList) {
                consumer.accept(batchSize); // inform each listener that we are skipping this many entries
            }
        }
        finally { // We need to set the next page end point no matter the outcome of the try catch. N.B. this gets executed even if there is a break
            if(resp == null) {
                // no next possible
                setNextPageEndPoint(null);   // don't consider next; we reached the max
                this.thisPage = null;
            } else {
                if(currentPageNumber > maxPages - 1) {
                    // because a request has been made already, so reduce by 1
                    setNextPageEndPoint(null); // don't consider next; we reached the max
                } else {
                    // else consider next page
                    setNextPageEndPoint(constructNextPageEndPoint(pageUrl, resp));
                }
                this.thisPage = this.parseResult(resp);

                setTotalCount(resp.getInt("totalResults"));
            }
        }
    }
}

编辑我忘了提及,当我说它总是评估为null时,我的意思是我的IDE - Intellij IDEA,警告我if条件总是计算为null。以下是Intellij中显示的帮助(使用Ctrl-F1)。

 Condition 'resp == null' is always 'true' less... (Ctrl+F1) 
 This inspection analyzes method control and data flow to report possible conditions that are always true or false, expressions whose value is statically proven to be constant, and situations that can lead to nullability contract violations.
 Variables, method parameters and return values marked as @Nullable or @NotNull are treated as nullable (or not-null, respectively) and used during the analysis to check nullability contracts, e.g. report possible NullPointerException errors.
More complex contracts can be defined using @Contract annotation, for example:
@Contract("_, null -> null") — method returns null if its second argument is null @Contract("_, null -> null; _, !null -> !null") — method returns null if its second argument is null and not-null otherwise @Contract("true -> fail") — a typical assertFalse method which throws an exception if true is passed to it 
The inspection can be configured to use custom @Nullable
@NotNull annotations (by default the ones from annotations.jar will be used)

编辑2 事实证明,代码分析是错误的,一旦运行,该值为非null。感谢大家(包括评论员)分享您的见解和建议。最后,我在条件之前插入了一个带有值的logger.info,一切似乎都有效。它似乎停止工作的原因是因为图形服务器正在运行超时。

2 个答案:

答案 0 :(得分:0)

这是正常行为。这个电话

apiClient.failSafeGet(pageUrl, getRetryCount());

抛出异常,因此resp的值赋值永远不会完成,所以finally block中的值为null。所以,要么你的方法总是抛出一个异常,要么就是,它会在某个时刻返回null

答案 1 :(得分:0)

在您的代码中:

 $(this).next('input[type="submit"]').css("background", "red").click();

如果try { resp = apiClient.failSafeGet(pageUrl, getRetryCount()); break; } catch (MalformedJsonException e) { logger.info(String.format("The json was still broken after %d retries. Skipping this page and notifying listeners", getRetryCount())); for (Consumer<Integer> consumer: onSkipListenerList) { consumer.accept(batchSize); // inform each listener that we are skipping this many entries } } finally {..... 抛出异常,则resp将始终为null,因为程序在协助实例重新执行之前失败。