繁体   English   中英

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

[英]Java 8 - effectively final variables, lambdas and try/catch/finally block

所以我开始玩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();
    }
}

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

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

PDDocument newDocument = null;
PDDocument oldDocument = null;

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

怎么去这个?

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

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

谢谢。

适当的解决方案是尝试资源。

没有它,你需要手动嵌套一些try / finally块:

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

谢谢大家的想法。 如果没有资源试用,似乎没有“好”的方法。 以下是使用try-with-resources的示例。

public void insertBlankPages(File inputFile, String outputFile, final int OFFSET) {
    try (PDDocument newDocument = createNewDocument();
         PDDocument 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();
    }
}

简单的解决方法是使用一个数组 ,它本身是最终的,所以你可以在lambda中引用它,但它的内容可以自由改变。

此代码与您的代码基本相同,但没有编译错误:

public void insertBlankPages(File inputFile, String outputFile, final int OFFSET) {
    PDDocument[] newDocument = new PDDocument[1]; // automatically filled with a null
    PDDocument oldDocument = null;
    try {
        newDocument[0] = createNewDocument();
        oldDocument = createOldDocument(inputFile);
        List<PDPage> oldPages = getAllPages(oldDocument);

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

        newDocument[0].save(outputFile);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (COSVisitorException e) {
        e.printStackTrace();
    } finally {
        if (newDocument[0] != null)
            newDocument[0].close();
        if (oldDocument != null)
            oldDocument.close();
    }
}

暂无
暂无

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

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