without with try the examples catch java try-with-resources autocloseable

java - the - ¿Por qué el bloque catch de try-with-resources es selectivamente opcional?



try with resources java (4)

Es opcional si close() no puede lanzar una excepción marcada. Sin embargo, si close() puede, entonces una excepción marcada tendría que manejarse de manera normal, ya sea con un bloque catch , o lanzando desde el método en el que está el bloque try-with-resources .

Más detalles están en JLS 14.2.3

14.20.3.2. Prueba-con-recursos extendidos

Una declaración try-with-resources con al menos una cláusula catch y / o una cláusula finally se denomina una declaración extendida try-with-resources.

El significado de una declaración extendida de prueba con recursos:

try ResourceSpecification Block [Catches] [Finally]

viene dada por la siguiente traducción a una declaración básica try-with-resources anidada dentro de una declaración try-catch o try-finally o try-catch-finally:

try { try ResourceSpecification Block } [Catches] [Finally]

El efecto de la traducción es poner la especificación de recursos "dentro" de la instrucción try. Esto permite que una cláusula catch de una declaración de prueba con recursos extendida detecte una excepción debido a la inicialización o cierre automático de cualquier recurso.

Además, todos los recursos se habrán cerrado (o se intentará cerrar) en el momento en que se ejecute finalmente el bloque, de acuerdo con la intención de la palabra clave finally.

¿Reflexiones sobre si esto está relacionado o no con el uso de una fuente de datos JNDI?

Sí lo es.

En el ejemplo del bloque try-with-resourses que proporcionó, es necesario detectar la excepción y manejar el método en el que se encuentra el bloqueo, ya que SQLException es una excepción comprobada.

Leí que el bloque catch en try-with-resources es opcional. Intenté crear un objeto Connection en un bloque try-with-resources, sin bloque catch posterior, solo para obtener un error de compilación de eclipse: "Excepción de tipo no SQLException lanzada por la invocación automática close() ".

Dado que cada recurso que se puede usar en try-with-resources implementa AutoCloseable , y potencialmente lanza una excepción al invocar el método close() , no entiendo cómo la cláusula catch es opcional, dado que no me permite saltar captura de la excepción de close() .

¿Hay algún requisito especial para que la implementación específica de AutoCloseable no declare directamente ninguna excepción lanzada en su método close() ? (por ejemplo, anular AutoCloseable ''s close() throws Exception con un close() que no lanza ninguna Exception)?

..o es posiblemente un problema de eclipse?

Edición: Aquí está el fragmento de código más simple que todavía causa el problema:

try (Connection con = dataSource.getConnection()) { /*...*/ }

¿Reflexiones sobre si esto está relacionado o no con el uso de una fuente de datos JNDI?

Gracias por adelantado.


No todas las clases de Java (!) Lanzan una excepción. A veces, solo desea utilizar un try-with-resources para usar la función de cierre automático, y nada más.

BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { if (br != null) br.close(); }

Esta captura es opcional porque readLine () no lanza una excepción (marcada).

Sí, close () podría lanzar una excepción, pero el try-with-resources se encarga de eso también.

try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); }

Así que este intento con recursos no necesita una trampa.


Podría simplemente estar lanzando la excepción (o capturándola en otro bloque try-catch):

private static void test() throws IOException { try(InputStream is = new FileInputStream("test.txt")) { while(is.read() > -1) { } } finally { // Will get executed, even if exception occurs System.out.println("Finished"); } }


Puede consultar el JLS, pero en realidad hay un razonamiento relativamente fácil por el que esta es la única forma correcta en que debe comportarse el idioma.

La regla principal de las excepciones marcadas es que cualquier excepción marcada declarada por un método debe manejarse, ya sea capturándola o dejando que el método que llama lo lance.

El try-with-resources siempre (implícitamente) llama al método close.

Entonces, si el método de cierre específico del AutoClosable que usa (determinado por el tipo declarado en el intento ) declara lanzar una excepción marcada, como una SQLException, debe manejar esta excepción marcada en algún lugar, ¡de lo contrario sería posible violar la regla!

Si el método de cierre no declara que lanza una excepción marcada, la regla no se infringe y no es necesario que maneje una excepción marcada para llamar implícitamente al método de cierre. En realidad, es un error de compilación si intenta detectar una excepción marcada que nunca se declaró como lanzada.