![](/img/trans.png)
[英]How to make final variables declared in a try block to be used in catch / finally block?
[英]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.