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产生的异常(如果真的产生异常的话)。