Saltar al contenido

Java: ¿Significado de catch (final SomeException e)?

El paso a paso o código que hallarás en este post es la solución más eficiente y válida que encontramos a esta inquietud o dilema.

Solución:

Básicamente significa:

Capture “SomeExceptionType” en la variable “e” con la promesa de que no asignaremos una excepción diferente a “e” durante el procesamiento de la excepción.

En su mayoría, esto es exagerado, como si estuviera detectando una excepción en un nombre de variable temporal (e solo es válido para el bloque de manejo de excepciones), no tengo que controlarme tan estrictamente como para no confiar en mí mismo para asignar un ( posiblemente creado) excepción al mismo nombre de variable.

Dicho esto, tal vez este bloque sea mantenido en gran medida por un equipo de personas de mentalidad diferente, y uno solo quería estar MUY seguro de que e era la excepción capturada original.

—- Editado en respuesta al comentario —-

No puedo pensar en una razón realmente excelente para hacer esto. Dado que “e” no es miembro (static o de lo contrario) el nombre “e” no será utilizado por la compilación posterior del archivo de clase. Otra forma de decir esto es que cuando ingresa al bloque de manejo de excepciones del código de bytes de JVM, el objeto no se asignará a ninguno de los nombres de miembros accesibles por el marco de procesamiento de JVM, sino que se enviará a la pila de procesamiento interno del Thread. marco actual.

Incluso si dos subprocesos tuvieran acceso al mismo objeto, cada subproceso tendría su propio marco, por lo que el compilador eliminó el nombre “e” de la pila interna de un marco y no pudo ser alterado por el otro subproceso.

Con eso en mente, el único beneficio de declarar “e” final es asegurarse de que los futuros codificadores no establezcan accidentalmente “e” después de ingresar al bloque. Quizás tenían la intención de hacer que el código fuera más robusto en un entorno de múltiples subprocesos, pero las variables temporales (aquellas con nombres que solo son válidos en el bloque) no tienen nombres después de la compilación, se insertan en la pila del marco.

Es por eso

public int safe() 
  int x = 5;
  x = x + 5;
  return x;

generalmente se considera seguro para subprocesos, porque hace esto (en pseudo código de bytes)

(In the thread's current frame)
push 5
push 5
add integers
return

Si bien esto no es seguro para subprocesos

int x = 5;

public void unsafe() 
  x = 5;
  x = x + 5;
  return x;

porque hace esto

(in the thread's current frame)
push "this"
push 5
set member x
push "this"
get member x
push 5
add integer
set member x
get member x
return

El último bytecode hace evidente que el entrelazado de dos subprocesos crea comunicaciones de subproceso a subproceso utilizando el miembro x y un intermediario, mientras que el primer bloque de código no puede tener ninguna comunicación entre subprocesos porque no hay intermediario.

Actualmente significa final muy similar a cualquier variable local, excepto que siempre está “definitivamente asignada”.

En compilaciones recientes de JDK7, un cambio de idioma de Project Coin le permite indicar un grado de implícita static se está escribiendo. Un solo catch puede capturar una serie de excepciones comprobadas diferentes por un tipo de base común, y volver a lanzar con el contexto adjunto solo teniendo capturas o declarando aquellas excepciones que podrían (hablando estáticamente) ser lanzadas dentro del try. (Consulte el enlace para obtener una mejor explicación).

La pregunta “¿Qué final hacer? “se aborda en otras respuestas a esta pregunta, y aquí, aquí y aquí. Pero en el contexto de una trata de atraparlo bloque, la Especificación del lenguaje Java (JLS) §4.12.4 establece (énfasis mío):

  • Un recurso de un declaración try-with-resources (§14.20.3) y un parámetro de excepción de un cláusula de captura múltiple (§14.20) son implícitamente declarado final.
  • Un parámetro de excepción de un cláusula uni-catch (§14.20) puede ser efectivamente final en lugar de declararse explícitamente final. Tal parámetro es nunca declarado implícitamente final.

En una cláusula de captura múltiple:

Añadiendo el final palabra clave a una cláusula de captura múltiple simplemente hace explícito el hecho de que el variable es implícitamente final. En general, siempre que el final La palabra clave transmite información adicional que ayuda a que su código sea más legible / fácil de mantener, úselo.

En una cláusula uni-catch

Por otro lado, el parámetro de excepción en un cláusula uni-catch es Nunca implícitamente final. Entonces, usando el final palabra clave a una cláusula uni-catch evita que suceda algo como lo siguiente:

try {
     throw new Exception();
catch (Exception e)
    e = null;
    e.printStackTrace(); //throws a NullPointerException

El problema es obvio en este sencillo ejemplo. Pero dos casos pueden ser menos obvios y justificar el uso de final:

  1. Si el bloque de captura es más complicado, es posible una reasignación accidental. (Aunque, si el bloque de captura es complicado, probablemente lo esté haciendo mal).
  2. Para evitar problemas causados ​​durante el mantenimiento del código. Añadiendo final a la variable de excepción garantizará que la reasignación se detecte en la compilación, en lugar de tiempo de ejecución

Como regla general, utilice la final palabra clave en una cláusula uni-catch de la misma manera que usarías el final palabra clave para un parámetro de método:

JLS§4.12.4: Declarar una variable como final puede servir como documentación útil de que su valor no cambiará y puede ayudar a evitar errores de programación.

Te mostramos reseñas y puntuaciones

Si guardas algún incógnita y disposición de regenerar nuestro sección puedes añadir una explicación y con mucho gusto lo observaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *