从 Java 7 开始,您应该使用 try-with-resources
try(Scanner sc1 = new Scanner("");
Scanner sc2 = new Scanner("");
Scanner sc3 = new Scanner("")){
}
//all scanners get closed implicitly
所以您根本不需要任何代码。
所有 for-each 或流构造的问题是,理论上 - 如果第一个 close() 在调用底层源的 close() 方法时出现异常,则以下扫描程序将不会关闭。 Scanner.close() 实现会捕获任何 IOException,但不会捕获其他可能发生的异常。
try-with-resources 结构可以解决这个问题,而循环则不会。
编辑:虽然您的问题针对的是更通用的方法,但上述解决方案是对您的特定问题的回应:处理 AutoCloseable 资源,无论如何都应该与try-with-resources 构造,根本不需要对 close 方法进行特殊处理(= 您特定问题的最短解决方案)。
关于处理任意项目(不是资源)的更一般的问题,Java 至少有两种选择:
从 Array/Varargs 创建一个列表并对其进行迭代
for(YourItemType item : Arrays.asList(your,items,here)) {
//do something
}
从 Array/Varargs 创建一个 Stream 并对其应用函数
Stream.of(your,items,here).forEach(item -> { doSomething});
当然“doSomething”可以替换为方法引用
Stream.of(your,items,here).forEach(this::myMethod);
...
void myMethod(YourItemType item){
//doSomething
}
这种方法的问题是,检查的异常必须在 lambda 表达式中显式处理。让我们以上面的例子,让myMethod抛出一个检查异常
void myMethod(YourItemType item) throws Exception
在这种情况下,您的流语句必须看起来像
Stream.of(your,items,here).forEach(item -> {
try {
myMethod(item);
} catch (Exception e){
//omit or throw new RuntimeException(e);
};
这看起来不太好。但是我们可以将 lambda 主体放在一个单独的方法中
void myMethodQuietly(YourItemType item) {
try {
myMethod(item);
}catch(Exception e){
//omit or throw new RuntimeException(e);
}
}
Stream.of(your,items,here).forEach(this::myMethodQuietly);
这种方法可能对您的特定资源问题感兴趣。我们可以将所有这些放入一个 CompositeAutoCloseable 中,该 CompositeAutoCloseable 获取在类之外创建的资源,所有这些资源都应该在调用 close() 时安全关闭
public class CompositeAutoCloseable implements AutoCloseable {
private List<Closeable> resources;
public CompositeAutoCloseable(Closeable... resources) {
this.resources = Arrays.asList(resources);
//you could use a stream here too
}
@Override
public void close() {
this.resources.stream().forEach(this::closeQuietly);
}
void closeQuietly(Closeable res) {
if(res == null) {
return;
}
try {
res.close();
}catch(Exception e){
//omit
}
}
}
一旦你有了这样一个帮助类,你就可以通过 try-with-resources 再次使用它。
try(CompositeAutoCloseable cac = new CompositeAutoCloseable(sc1,sc2,sc3)) {
//do something
}
与初始解决方案相比,我让您决定这是否有意义;)