ejemplo - Java: explicación de excepción marcada vs no comprobada




jtextfield (14)

  1. ¿Lo anterior se considera una excepción marcada? No El hecho de que esté manejando una excepción no la convierte en una excepción comprobada si se trata de una excepción RuntimeException.

  2. ¿Es RuntimeException una excepción sin marcar? Sí

Las excepciones marcadas son subclases de java.lang.Exception. Las excepciones no comprobadas son subclases de java.lang.RuntimeException.

Las llamadas que emiten excepciones marcadas deben incluirse en un bloque try {} o manejarse en un nivel superior en la persona que llama al método. En ese caso, el método actual debe declarar que lanza dichas excepciones para que las personas que llaman puedan hacer los arreglos apropiados para manejar la excepción.

Espero que esto ayude.

P: ¿Debo aumentar la excepción exacta o enmascararla utilizando Exception?

R: Sí, esta es una muy buena pregunta y una importante consideración de diseño. La excepción de clase es una clase de excepción muy general y puede usarse para envolver excepciones internas de bajo nivel. Sería mejor crear una excepción personalizada y envolverla dentro. Pero, y uno grande: nunca se oculta en la causa original subyacente. Por ejemplo, Dont ever hagas lo siguiente -

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException("Cannot login!!"); //<-- Eat away original root cause, thus obscuring underlying problem.
}

En su lugar, haga lo siguiente:

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException(sqle); //<-- Wrap original exception to pass on root cause upstairs!.
}

Comerse la causa original entierra la causa real, más allá de la recuperación, es una pesadilla para los equipos de soporte de producción a los que se les da acceso a todos los registros de aplicaciones y mensajes de error. Aunque este último es un mejor diseño, muchas personas no lo usan a menudo porque los desarrolladores simplemente no transmiten el mensaje subyacente a quien llama. Así que tome una nota firme: Always pass on the actual exception devuelva la Always pass on the actual exception ya sea envuelta o no en alguna excepción específica de la aplicación.

En la prueba RuntimeExceptions

Las excepciones RuntimeExceptions como una regla general no deben ser intentadas. En general, señalan un error de programación y deben dejarse solos. En su lugar, el programador debe verificar la condición de error antes de invocar algún código que podría resultar en una excepción RuntimeException. Por ejemplo:

try {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);
} catch (NullPointerException npe) {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

Esta es una mala práctica de programación. En su lugar, debería haberse realizado una comprobación nula como

if (userObject != null) {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);
} else {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

Pero hay ocasiones en que dicha comprobación de errores es costosa, como el formato de número, considere esto:

try {
    String userAge = (String)request.getParameter("age");
    userObject.setAge(Integer.parseInt(strUserAge));
} catch (NumberFormatException npe) {
   sendError("Sorry, Age is supposed to be an Integer. Please try again.");
}

Aquí, la comprobación de errores antes de la invocación no vale la pena porque esencialmente significa duplicar todo el código de conversión de cadena a entero dentro del método parseInt () y es propenso a errores si lo implementa un desarrollador. Así que es mejor simplemente eliminar el try-catch.

Por lo tanto, NullPointerException y NumberFormatException son RuntimeExceptions, la captura de una NullPointerException debe ser reemplazada por una comprobación nula elegante, mientras que recomiendo capturar una NumberFormatException explícitamente para evitar la posible introducción de código propenso a errores.

He leído varias publicaciones en StackOverFlow sobre excepciones comprobadas y no comprobadas. Sinceramente, todavía no estoy seguro de cómo usarlos correctamente.

Joshua Bloch en " Java efectiva " dijo que

Utilice excepciones comprobadas para condiciones recuperables y excepciones de tiempo de ejecución para errores de programación (Artículo 58 en la 2ª edición)

A ver si entiendo esto correctamente.

Aquí está mi comprensión de una excepción comprobada:

try{
    String userInput = //read in user input
    Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
    id = 0; //recover the situation by setting the id to 0
}

1. ¿Lo anterior se considera una excepción marcada?

2. ¿Es RuntimeException una excepción sin marcar?

Aquí está mi comprensión de una excepción sin marcar:

try{
    File file = new File("my/file/path");
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){

//3. What should I do here?
    //Should I "throw new FileNotFoundException("File not found");"?
    //Should I log?
    //Or should I System.exit(0);?
}

4. Ahora, ¿no podría el código anterior también ser una excepción comprobada? ¿Puedo intentar recuperar la situación así? ¿Puedo? (Nota: mi tercera pregunta está dentro de la catch arriba)

try{
    String filePath = //read in from user input file path
    File file = new File(filePath);
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){
    //Kindly prompt the user an error message
    //Somehow ask the user to re-enter the file path.
}

5. ¿Por qué la gente hace esto?

public void someMethod throws Exception{

}

¿Por qué dejan que brille la excepción? ¿No es mejor manejar el error antes? ¿Por qué burbuja?

EDITAR: ¿Debo aumentar la excepción exacta o enmascararla utilizando Exception?

A continuacion estan mis lecturas

En Java, ¿cuándo debería crear una excepción marcada y cuándo debería ser una excepción de tiempo de ejecución?

Cuándo elegir excepciones marcadas y no marcadas


1) No, una excepción NumberFormatException es una excepción sin marcar. A pesar de que lo atrapó (no está obligado a hacerlo), está desactivado. Esto se debe a que es una subclase de IllegalArgumentException que es una subclase de RuntimeException.

2) RuntimeException es la raíz de todas las excepciones sin marcar. Cada subclase de RuntimeException está desactivada. Todas las demás excepciones y Throwables están marcados, excepto los errores (que se incluyen en Throwable).

3/4) Podría alertar al usuario de que eligió un archivo inexistente y pedir uno nuevo. O simplemente deje de informarle al usuario que ingresó algo no válido.

5) Lanzar y atrapar 'Excepción' es una mala práctica. Pero de manera más general, puede lanzar otras excepciones para que la persona que llama pueda decidir cómo lidiar con eso. Por ejemplo, si escribió una biblioteca para manejar la lectura de alguna entrada de archivo y su método pasó un archivo inexistente, no tiene idea de cómo manejar eso. ¿La persona que llama quiere preguntar de nuevo o renunciar? Así que le devuelves la excepción a la persona que llama.

En muchos casos, se produce una excepción sin marcar porque el programador no verificó las entradas (en el caso de NumberFormatException en su primera pregunta). Por eso es opcional atraparlos, porque hay formas más elegantes de evitar generar esas excepciones.


Comprobado - propenso a suceder. Comprobado en tiempo de compilación.

Ej. .. FileOperations

Sin comprobar - Debido a datos incorrectos. Comprobado en tiempo de ejecución.

P.ej..

String s = "abc";
Object o = s;
Integer i = (Integer) o;

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at Sample.main(Sample.java:9)

Aquí la excepción se debe a datos erróneos y de ninguna manera se puede determinar durante el tiempo de compilación.


La JVM verifica las excepciones verificadas en el momento de la compilación y está relacionada con los recursos (archivos / db / stream / socket, etc.). El motivo de la excepción comprobada es que, en el momento de la compilación, si los recursos no están disponibles, la aplicación debe definir un comportamiento alternativo para manejar esto en el bloque catch / finally.

Las excepciones no verificadas son puramente errores programáticos, cálculos erróneos, datos nulos o incluso fallas en la lógica de negocios que pueden llevar a excepciones en tiempo de ejecución. Está absolutamente bien para manejar / capturar excepciones sin marcar en el código.

Explicación tomada de http://coder2design.com/java-interview-questions/


Para responder a la pregunta final (los demás parecen estar completamente respondidos más arriba), "¿Debo aumentar la excepción exacta o enmascararla utilizando la excepción?"

Supongo que quieres decir algo como esto:

public void myMethod() throws Exception {
    // ... something that throws FileNotFoundException ...
}

No, siempre declare la excepción más precisa posible, o una lista de tales. Las excepciones que usted declara que su método es capaz de lanzar forman parte del contrato entre su método y la persona que llama. Lanzar "FileNotFoundException" significa que es posible que el nombre del archivo no sea válido y que no se encuentre el archivo; la persona que llama tendrá que manejar eso de manera inteligente. Lanzar "Excepción" significa "Oye, sh * t sucede. Repartir". Que es una API muy pobre.

En los comentarios sobre el primer artículo hay algunos ejemplos en los que "arroja Excepciones" es una declaración válida y razonable, pero ese no es el caso de la mayoría del código "normal" que escribirá.


Si algo es una "excepción comprobada" no tiene nada que ver con si lo atrapa o lo que hace en el bloque catch. Es una propiedad de las clases de excepción. Cualquier cosa que sea una subclase de Exception excepto RuntimeException y sus subclases, es una excepción comprobada.

El compilador de Java lo obliga a capturar excepciones marcadas o declararlas en la firma del método. Se suponía que mejoraría la seguridad del programa, pero la opinión de la mayoría parece ser que no vale la pena por los problemas de diseño que crea.

¿Por qué dejan que brille la excepción? ¿No se maneja el error cuanto antes mejor? ¿Por qué burbuja?

Porque ese es todo el punto de las excepciones. Sin esta posibilidad, no necesitarías excepciones. Le permiten manejar los errores en el nivel que elija, en lugar de obligarlo a lidiar con ellos en métodos de bajo nivel donde se producen originalmente.


¿Por qué dejan que brille la excepción? ¿No es mejor manejar el error antes? ¿Por qué burbuja?

Por ejemplo, digamos que tiene alguna aplicación cliente-servidor y el cliente ha realizado una solicitud de algún recurso que no se pudo encontrar o por algún otro error podría haber ocurrido en el lado del servidor al procesar la solicitud del usuario, entonces es su deber del servidor para decirle al cliente por qué no pudo obtener lo que solicitó, por lo que para lograrlo en el servidor, se escribe el código para lanzar la excepción usando la palabra clave throw en lugar de tragarlo o manejarlo. De esta forma, no habrá posibilidad de intimidar al cliente sobre el error que se ha producido.

Nota: Para proporcionar una descripción clara de qué tipo de error se ha producido, podemos crear nuestro propio objeto de Excepción y enviarlo al cliente.


Excepciones comprobadas :

  • Las excepciones verificadas por el compilador para una ejecución sin problemas del programa en tiempo de ejecución se denominan Excepción comprobada.

  • Estos ocurren en tiempo de compilación.

  • Si estos no se manejan correctamente, darán un error de tiempo de compilación (no excepción).
  • Todas las subclases de la clase de excepción, excepto la excepción RuntimeException, se revisan como excepción.

    Ejemplo hipotético : suponga que va a salir de su casa para el examen, pero si comprueba si se llevó el ticket de entrada a su casa (tiempo de compilación), no habrá ningún problema en la sala de exámenes (tiempo de ejecución).

Excepción no marcada :

  • Las excepciones que no son verificadas por el compilador se denominan Excepciones no verificadas.

  • Estos ocurren en tiempo de ejecución.

  • Si estas excepciones no se manejan adecuadamente, no dan error de tiempo de compilación. Pero el programa terminará prematuramente en el tiempo de ejecución.

  • Todas las subclases de RunTimeException y Error son excepciones sin marcar.

    Ejemplo hipotético : suponga que se encuentra en la sala de examen pero de alguna manera su escuela tuvo un accidente de incendio (significa en tiempo de ejecución) en el que no puede hacer nada en ese momento pero se pueden tomar precauciones antes (tiempo de compilación).


Creo que las excepciones marcadas son un buen recordatorio para el desarrollador que usa una biblioteca externa de que las cosas pueden ir mal con el código de esa biblioteca en situaciones excepcionales.

Lea más sobre las excepciones verificadas y no verificadas aquí http://learnjava.today/2015/11/checked-vs-unchecked-exceptions/


Si alguien se preocupa por otra prueba que no le guste las excepciones marcadas, vea los primeros párrafos de la popular biblioteca JSON:

"Aunque esta es una excepción marcada, rara vez es recuperable. La mayoría de las personas que llaman deberían simplemente envolver esta excepción en una excepción no verificada y volver a realizarla:"

Entonces, ¿por qué alguien haría que los desarrolladores siguieran verificando la excepción, si en lugar de eso simplemente "lo envolviéramos"? jajaja

http://developer.android.com/reference/org/json/JSONException.html


Aquí hay una regla simple que puede ayudarte a decidir. Está relacionado con cómo se usan las interfaces en Java.

Tome su clase e imagine el diseño de una interfaz para tal que la interfaz describa la funcionalidad de la clase pero ninguna de las implementaciones subyacentes (como debería ser una interfaz) Imagina que podrías implementar la clase de otra manera.

Mire los métodos de la interfaz y considere las excepciones que podrían lanzar:

Si un método puede lanzar una excepción, independientemente de la implementación subyacente (en otras palabras, solo describe la funcionalidad), entonces probablemente debería ser una excepción marcada en la interfaz.

Si una excepción es causada por la implementación subyacente, no debería estar en la interfaz. Por lo tanto, debe ser una excepción no verificada en su clase (ya que las excepciones no verificadas no tienen que aparecer en la firma de la interfaz), o debe ajustarlo y volver a emitir como una excepción marcada que forma parte del método de la interfaz.

Para decidir si debe ajustar y volver a generar, debe considerar nuevamente si tiene sentido para un usuario de la interfaz tener que manejar la condición de excepción de inmediato, o si la excepción es tan general que no hay nada que pueda hacer al respecto y debería propagar por la pila. ¿Tiene sentido la excepción envuelta cuando se expresa como la funcionalidad de la nueva interfaz que está definiendo o es solo un proveedor de una bolsa de posibles condiciones de error que también podrían ocurrir con otros métodos? Si es el primero, aún podría ser una excepción marcada, de lo contrario debería estar desactivada.

Por lo general, no debe planear "aumentar" las excepciones (capturar y volver a lanzar). La persona que llama debe manejar una excepción (en cuyo caso está marcada) o debe ir hasta un controlador de alto nivel (en cuyo caso es más fácil si no está marcada).


En resumen, las excepciones que su módulo o módulos anteriores deben manejar durante el tiempo de ejecución se denominan excepciones de verificación, otras son excepciones sin verificar que son RuntimeExceptiono Error. En este video, explica las excepciones marcadas y no marcadas en java. https://www.youtube.com/watch?v=ue2pOqLaArw


Solo para señalar que si lanza una excepción marcada en un código y la captura está en algunos niveles arriba, debe declarar la excepción en la firma de cada método entre usted y la captura. Por lo tanto, la encapsulación se interrumpe porque todas las funciones en la ruta de lanzamiento deben conocer los detalles de esa excepción.


Todos esos son excepciones verificadas. Las excepciones no verificadas son subclases de RuntimeException. La decisión no es cómo manejarlos, es si su código los lanza. Si no quiere que el compilador le diga que no ha manejado una excepción, entonces use una excepción no verificada (subclase de RuntimeException). Deben guardarse para situaciones de las que no pueda recuperarse, como errores de memoria y similares.





unchecked-exception