javatry-with-resources

Why can't I pass lambda inline into try-with-resources


Help me understand why the following code doesn't compile. AutoCloseable is a single abstract method interface and I am able to assign it to lambda expression, just not in try-with-resources context:

class Main {
  public static void main(String[] args) {
    try (AutoCloseable test = () -> System.out.println("Closing")) {}
  }
}

I'm getting following compilation error and trying to wrap my head around - why?

error: unreported exception Exception; must be caught or declared to be thrown

exception thrown from implicit call to close() on resource variable 'test'


Solution

  • Your problem is not due to implementing java.lang.AutoCloseable as a lambda. That interface, at least as of Java 23, only has a single abstract method and is therefore capable of being implemented as a lambda expression or method reference.

    The problem is that a try-with-resources statement will automatically and implicitly call close(), and that method is declared to be able to throw Exception. That is a checked exception type which means you must explicitly handle it.

    There are two solutions (not including using or creating your own subtype of AutoCloseable; see this answer).

    1) Declare the caller method to be able to throw Exception
    class Main {
      // Declare that 'main' can also throw Exception
      public static void main(String[] args) throws Exception {
        try (AutoCloseable test = () -> System.out.println("Closing")) {}
      }
    }
    
    2) Catch the exception
    class Main {
      public static void main(String[] args) {
        try (AutoCloseable test = () -> System.out.println("Closing")) {
        } catch (Exception ex) {
          // handle 'ex'
        }
      }
    }