https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.3
Optionally replace a try statement with the desugaring of a try-with-resources statement. The canonical desugaring of
try ResourceSpecification
Block
is
{
final VariableModifiers_minus_final R #resource = Expression;
Throwable #primaryException = null;
try ResourceSpecificationtail
Block
catch (Throwable #t) {
#primaryException = t;
throw #t;
} finally {
if (#resource != null) {
if (#primaryException != null) {
try {
#resource.close();
} catch(Throwable #suppressedException) {
#primaryException.addSuppressed(#suppressedException);
}
} else {
#resource.close();
}
}
}
举个解语法糖的例子,如下:
public class TryCatchFinally {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("AutoCloseTest.java"));
PrintStream ps = new PrintStream(new FileOutputStream("readme.txt"))) {
System.out.println(br.readLine());
} catch (Exception e) {
e.printStackTrace();
}finally{
System.out.println("default");
}
}
}
调用Lower类的visitTry()方法,传递的参数Tree如下截图所示。
final BufferedReader br = new BufferedReader(new FileReader("AutoCloseTest.java"));
/*synthetic*/ Throwable primaryException0$ = null;
try {
final PrintStream ps = new PrintStream(new FileOutputStream("readme.txt"));
/*synthetic*/ Throwable primaryException1$ = null;
try {
System.out.println(br.readLine());
} catch (/*synthetic*/ final Throwable t$) {
primaryException1$ = t$;
throw t$;
} finally {
if (ps != null)
if (primaryException1$ != null) try {
ps.close();
} catch (Throwable x2) {
primaryException1$.addSuppressed(x2);
}
else ps.close();
}
} catch (/*synthetic*/ final Throwable t$) {
primaryException0$ = t$;
throw t$;
} finally {
if (br != null)
if (primaryException0$ != null) try {
br.close();
} catch (Throwable x2) {
primaryException0$.addSuppressed(x2);
}
else br.close();
由如上的代码可知,如果try块产生了异常,则会忽略close产生的异常(如果真的产生异常的话);否则才会抛出close产生的异常(如果真的产生异常的话)。