Reputation: 315
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'
Upvotes: 0
Views: 109
Reputation: 45816
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).
class Main {
// Declare that 'main' can also throw Exception
public static void main(String[] args) throws Exception {
try (AutoCloseable test = () -> System.out.println("Closing")) {}
}
}
class Main {
public static void main(String[] args) {
try (AutoCloseable test = () -> System.out.println("Closing")) {
} catch (Exception ex) {
// handle 'ex'
}
}
}
Upvotes: 4
Reputation: 4044
Option 3 for the answer here would be to define your own implementation of java.lang.AutoCloseable
where the method close()
does not declare an exception at all:
public interface MyCloseable extends AutoCloseable
{
@Override
public void close();
}
public static final void main( final String... args )
{
try( final MyCloseable test = () -> System.out.println( "Closing" ) )
{ /*Do something*/ }
}
Upvotes: 4