Java 8 - 有效的最终变量、lambda 和 try/catch/finally 块

Srk*_*kic 5 java lambda finally try-catch

因此,我开始使用 Java 8 流/lambda 表达式,并遇到了一些有趣的问题,我不太确定如何解决。所以我在这里请求你的帮助。

有问题的示例代码:

public void insertBlankPages(File inputFile, String outputFile, final int OFFSET) {
    PDDocument newDocument;
    PDDocument oldDocument;
    try {
        newDocument = createNewDocument();
        oldDocument = createOldDocument(inputFile);
        List<PDPage> oldPages = getAllPages(oldDocument);

        oldPages.stream()
                .limit(oldPages.size() - OFFSET)
                .forEach(page -> {
                    newDocument.addPage(page);
                    newDocument.addPage(new PDPage(page.getMediaBox()));
                });

        newDocument.save(outputFile);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (COSVisitorException e) {
        e.printStackTrace();
    } finally {
        newDocument.close();
        oldDocument.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

对于上面的代码,编译器抱怨在finally块中调用了close()。错误是:“变量 newDocument 可能尚未初始化”。旧文档也一样。

当然,我继续初始化变量,如下所示:

PDDocument newDocument = null;
PDDocument oldDocument = null;
Run Code Online (Sandbox Code Playgroud)

现在我收到编译器错误“lambda 表达式中使用的变量应该是有效的最终变量”。

这件事该怎么办呢?

createNewDocument 和 createOldDocument 方法会抛出异常,因此调用必须在 try/catch 块内。我还需要关闭finally 块中的文档。

我应该能够通过使用 try-with-resources 来解决这个问题。但是,我很想知道是否有其他合适的解决方案。

谢谢。

Thi*_*ilo 3

正确的解决方案是尝试资源。

如果没有它,您需要手动嵌套更多 try/finally 块:

try {
    PDDocument newDocument = createNewDocument();
    try{           
       PDDocument oldDocument = createOldDocument(inputFile);
       try{
          // .....
       }
       finally { oldDocument.close() }
    }
    finally{ newDocument.close(); }
}
catch (IOException e) {
    e.printStackTrace();
} 
Run Code Online (Sandbox Code Playgroud)