Este artículo resume las 10 preguntas más frecuentes sobre las excepciones de Java.
1. Marcado frente a no marcado
En resumen, las excepciones comprobadas deben capturarse explícitamente en un método o declararse en la cláusula throws del método. Las excepciones no marcadas son causadas por problemas que no se pueden resolver, como dividir por cero, puntero nulo, etc. Las excepciones marcadas son especialmente importantes porque espera que otros desarrolladores que usan su API sepan cómo manejar las excepciones.
Por ejemplo, IOException es una excepción marcada de uso común y RuntimeException es una excepción no marcada. Puede consultar el diagrama de jerarquía de excepciones de Java antes de leer el resto.
2. Mejores prácticas para la gestión de excepciones
Si una excepción se puede manejar correctamente, debe detectarse; de lo contrario, debe lanzarse.
3. ¿Por qué las variables definidas en try no se pueden utilizar en catch o finalmente?
En el siguiente código, la cadena s declarada en el bloque try no se puede usar en la cláusula catch. El código no pasa la compilación.
try {
File file = new File("path");
FileInputStream fis = new FileInputStream(file);
String s = "inside";
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println(s);
}
|
intente {Archivo archivo = nuevo Archivo («ruta»); FileInputStream fis = nuevo FileInputStream (archivo); String s = «dentro»; } captura (FileNotFoundException e) {e.printStackTrace (); System.out.println (s); }
La razón es que no sabe en qué parte del bloque try se lanzaría la excepción. Es muy posible que la excepción se lance antes de que se declare el objeto. Esto es cierto para este ejemplo en particular.
4. ¿Por qué Double.parseDouble (null) e Integer.parseInt (null) arrojan excepciones diferentes?
De hecho, arrojan diferentes excepciones. Este es un problema de JDK. Están desarrollados por diferentes desarrolladores, por lo que no vale la pena pensarlo demasiado.
Integer.parseInt(null);
// throws java.lang.NumberFormatException: null
Double.parseDouble(null);
// throws java.lang.NullPointerException
|
Integer.parseInt (nulo); // lanza java.lang.NumberFormatException: null Double.parseDouble (null); // lanza java.lang.NullPointerException
5. Excepciones de tiempo de ejecución de uso común en Java
Aquí hay sólo algunos de ellos.
IllegalArgumentException
ArrayIndexOutOfBoundsException
Se pueden usar en la instrucción if cuando la condición no se cumple de la siguiente manera:
if (obj == null) {
throw new IllegalArgumentException("obj can not be null");
|
if (obj == null) {throw new IllegalArgumentException («obj no puede ser nulo»);
6. ¿Podemos detectar varias excepciones en la misma cláusula catch?
La respuesta es sí. Siempre que esas clases de excepción puedan rastrear hasta la misma superclase en la jerarquía de herencia de clases, solo puede usar esa superclase.
7. ¿Puede el constructor lanzar excepciones en Java?
La respuesta es sí. Constructor es un método especial. Aquí hay un ejemplo de código.
8. Lanzar una excepción en la cláusula final
Es legal hacer lo siguiente:
public static void main(String[] args) {
File file1 = new File("path1");
File file2 = new File("path2");
try {
FileInputStream fis = new FileInputStream(file1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
FileInputStream fis = new FileInputStream(file2);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
|
public static void main (String[] args) {Archivo archivo1 = nuevo archivo («ruta1»); Archivo archivo2 = nuevo archivo («ruta2»); intente {FileInputStream fis = new FileInputStream (archivo1); } captura (FileNotFoundException e) {e.printStackTrace (); } finalmente {prueba {FileInputStream fis = new FileInputStream (archivo2); } captura (FileNotFoundException e) {e.printStackTrace (); }}}
Pero para tener una mejor legibilidad del código, debe envolver el bloque try-catch incrustado como un nuevo método, y luego poner la invocación del método en la cláusula finalmente.
public static void main(String[] args) {
File file1 = new File("path1");
File file2 = new File("path2");
try {
FileInputStream fis = new FileInputStream(file1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
methodThrowException();
}
}
|
public static void main (String[] args) {Archivo archivo1 = nuevo archivo («ruta1»); Archivo archivo2 = nuevo archivo («ruta2»); intente {FileInputStream fis = new FileInputStream (archivo1); } captura (FileNotFoundException e) {e.printStackTrace (); } finalmente {methodThrowException (); }}
9. Se puede volver a utilizar en el bloque finalmente.
Sí puede.
10. ¿Por qué los desarrolladores consumen excepciones de forma silenciosa?
Hay tantos segmentos de código de tiempo como los siguientes. Si manejar correctamente las excepciones es tan importante, ¿por qué los desarrolladores siguen haciéndolo?
try {
...
} catch(Exception e) {
e.printStackTrace();
}
|
try {…} catch (Exception e) {e.printStackTrace (); }
Ignorar es fácil. La ocurrencia frecuente no significa corrección.
Referencias:
1. Excepciones no comprobadas en Java
2. La raíz de la jerarquía de clases de excepción de Java
3. Preguntas relacionadas con las excepciones de Java en stackoverflow