OCP Prep Notes on TWRs

Try-with-Resources Constructs

  • See TWR? immediately check if the class implements AutoCloseable
  • See I/O operations? most of them throw IOE , therfore must be handled
  • try-with-resources MUST obey the Catch-or-Specify Requirement in case of ChEs
  • AutoCloseable resource vars are implicitly final
  • catch and finally are optional, hence  they will be executed AFTER the resource has been closed, which happens when the try block ends
  • AutoCloseable‘s close() throws an Exception
  • Closeable extends AutoCloseable and throws IOException rather than Exception; CAN be used in the TWR constructs
  • when autoclosing a resource throws an E, this E becomes suppressed if there was an E before it; HOWEVER, if a call to close() throws the very first E, this E will reveal itself or can be caught
  • getSuppressed() returns a Throwable
  • catch may not have a ChE except for Exception and Throwable when try doesn’t throw any ChE
  • resource should be created (declared and inited) inside the resource specification block:
Statement stmt = null;               // bad idea
Connection c = DriverManager.getConnection("jdbc:_smth_valid_", "app", "app");   // throws SQLException
try(stmt = c.createStatement();) {   // INVALID: should've been try(Statement stmt = c.createStatement();)
     ResultSet rs = stmt.executeQuery("select * from EMPLOYEE");
     while(rs.next()){
         System.out.println(rs.getString(0));
     }  }
catch(SQLException e){     System.out.println("Exception "); }
  • suppressed exceptions appear ONLY in the TWR constructs:
class Probe implements AutoCloseable {
    int id = 0;
    Probe(int id) { this.id = id; }
    public void close(){
        System.out.println("closing Probe #" + this.id);
        throw new RuntimeException("RTE from closing Probe #" + this.id);
    }
}

class Test{
    static void run(){
        System.out.println("in run");
        throw new RuntimeException("RTE from run"); }
    public static void main(String[] args) {
        try(
                Probe p1 = new Probe(1); Probe p2 = new Probe(2);     // t1
           ){
            run();
            throw new RuntimeException("RTE from try");
        }
        catch(RuntimeException rte ){
            int s = rte.getSuppressed().length;
            System.out.println("Number of suppressed exceptions: " + s );
            if (s!=0) for (Throwable t : rte.getSuppressed()) System.out.println(t.getMessage());
            System.out.println(rte.getMessage());
            throw new RuntimeException("RTE from catch");
        }
    }
}

Commenting t1 out will print smth similar to this:

in run
Number of suppressed exceptions: 0RTE from run
Exception in thread “main” java.lang.RuntimeException: RTE from catch

When t1 is operational, the output contains:

in run
closing Probe #2
closing Probe #1                                          // observe that resources are closed in reverse order
Number of suppressed exceptions: 2
RTE from closing Probe #2
RTE from closing Probe #1
RTE from run
Exception in thread “main” java.lang.RuntimeException: RTE from catch

  • resources are not even available in the optional catch or finally blocks

Leave Comment

Your email address will not be published. Required fields are marked *