引言

你可以使用@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后面的更新允许,我们将对此进行修复。

你依旧需要处理清除方法抛出的一切异常。

原文地址

——————————————————————————
行路不知花开处,蓦然回首芷兰香。