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如下截图所示。

Javac语法糖之TryCatchFinally-LMLPHP

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

  

05-11 02:16