引言
你可以使用@Cleanup注解确保代码执行路径退出当前作用于时清除制定资源。可以使用该注解标记局部变量,如下:
@Cleanup InputStream in = new FileInputStream("some/file");
其结果就是在该作用域的末尾将调用in.close()方法,并使用了try/finally代码块确认该方法一定执行。下面的示例中将展现该注解如何工作。
如果你想要标记一个没有close()方法的对象,但是有另一个没有参数的清除方法,可以像下面的代码中那样指定具体的清除方法名:
@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
默认情况下清除方法被认定为close()。包含一个或者多个参数的清除方法不能使用@Cleanup来进行调用。
使用Lombok
import lombok.Cleanup;
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
普通Java代码
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
}
支持的配置项
lombok.cleanup.flagUsage = [warning | error] (default: not set) 默认不进行设置,配置后Lombok将会把使用@Cleanup的类标记为错误或者警告。
小提示
在finally块中,仅在给定资源不为null时才调用清除方法。 但是,如果在代码上使用delombok,则会插入lombok.Lombok.preventNullAnalysis(Object o)并调用,以防止在静态代码分析可能确定不需要进行空检查时发出警告。 在类路径上使用lombok.jar进行编译会删除该方法调用,因此不存在运行时依赖性。
当作用域中的代码块抛出异常后,清除方法也抛出异常时,原异常将被清除方法抛出的异常所覆盖进而被隐藏。所以不可过度依赖这个特性。如果可以的话,Lombok想要成的代码时当主体代码块抛出异常时,清除方法抛出的异常就被静默吞噬(但是当主体代码以其他方式退出时则不进行吞噬)。Lombok的作者目前不知道该如何实现这个方法,但如果Java后面的更新允许,我们将对此进行修复。
你依旧需要处理清除方法抛出的一切异常。