Categorías
Diagram Exceptions

Diagrama de jerarquía de excepciones

En Java, la excepción se puede marcar o desmarcar. Ambos encajan en una jerarquía de clases. El siguiente diagrama muestra la jerarquía de clases de excepción de Java.

Son de color rojo comprobado excepciones. Cualquier excepción marcada que se pueda lanzar en un método debe ser capturada o declarada en la cláusula throws del método. Las excepciones marcadas deben detectarse en tiempo de compilación. Las excepciones marcadas se denominan así porque tanto el compilador de Java como la máquina virtual de Java comprueban que se obedezca esta regla. De color verde son desmarcar excepciones. Son excepciones que no se espera recuperar, como puntero nulo, dividir por 0, etc.

Consulte las 10 preguntas principales sobre las excepciones de Java.

Categorías
Exceptions

2 ejemplos para mostrar cómo funciona el manejo de excepciones de Java

Hay 2 ejemplos a continuación. Uno muestra que todos los métodos de llamada también necesitan manejar excepciones lanzadas por el método de llamada. El otro muestra que la superclase se puede usar para detectar o manejar excepciones de subclase.

El método de la persona que llama debe manejar las excepciones generadas por el método de la persona que llama

Aquí hay un programa que maneja excepciones. Simplemente pruebe eso, si se lanza una excepción en un método, no solo ese método, sino también todos los métodos que llaman a ese método tienen que declarar o lanzar esa excepción.

public class exceptionTest {
    private static Exception exception;
 
    public static void main(String[] args) throws Exception {
            callDoOne(); 
    }
 
    public static void doOne() throws Exception {
        throw exception;
    }
 
    public static void callDoOne() throws Exception {
        doOne();
    }
}

La superclase se puede usar para detectar o manejar excepciones de subclase

Lo siguiente también está bien, porque la superclase se puede usar para detectar o manejar excepciones de subclase:

class myException extends Exception{
 
}
 
public class exceptionTest {
    private static Exception exception;
    private static myException myexception;
 
    public static void main(String[] args) throws Exception {
            callDoOne(); 
    }
 
    public static void doOne() throws myException {
        throw myexception;
    }
 
    public static void callDoOne() throws Exception {
        doOne();
        throw exception;
    }
}

Esta es la razón por la que solo una clase padre en la cláusula catch es sintácticamente segura.

Categorías
Exceptions

¿Puede el constructor lanzar excepciones en Java?

1. La pregunta

En Java, los métodos pueden generar excepciones. ¿Los constructores también pueden lanzar excepciones? La respuesta es sí.

2. La razón y algunos antecedentes necesarios

Un constructor es solo un método especial. En esta perspectiva, seguramente puede hacer lo que pueden hacer los métodos regulares.

Es posible que haya algunos objetos creados y asignados a campos estáticos antes de que se complete el método constructor. En este caso, el objeto que se debe crear aún no se crea. Así que debes tener cuidado con la consistencia.

Aquí hay un método constructor de ejemplo que lanza una excepción.

class FileReader{
	public FileInputStream fis = null;
 
	public FileReader() throws IOException{
		File dir = new File(".");//get current directory
		File fin = new File(dir.getCanonicalPath() + 
                          File.separator + "not-existing-file.txt");
		fis = new FileInputStream(fin);
	}
}

Si desea conocer las mejores prácticas del manejo de excepciones de Java, le recomiendo esta publicación.

Categorías
Exceptions Top 10

Las 10 preguntas principales sobre las excepciones de Java

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);
}

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

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");

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();
		}
	}
}

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();
	}
}

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();
}

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

Categorías
Exceptions I/O

¿Debería colocarse .close () en el bloque finalmente o no?

Las siguientes son 3 formas diferentes de cerrar un escritor de salida. El primero pone el método close () en la cláusula try, el segundo pone close en la cláusula finalmente y el tercero usa una declaración try-with-resources. ¿Cuál es el correcto o el mejor?

//close() is in try clause
try {
	PrintWriter out = new PrintWriter(
			new BufferedWriter(
			new FileWriter("out.txt", true)));
	out.println("the text");
	out.close();
} catch (IOException e) {
	e.printStackTrace();
}
//close() is in finally clause
PrintWriter out = null;
try {
	out = new PrintWriter(
		new BufferedWriter(
		new FileWriter("out.txt", true)));
	out.println("the text");
} catch (IOException e) {
	e.printStackTrace();
} finally {
	if (out != null) {
		out.close();
	}
}
//try-with-resource statement
try (PrintWriter out2 = new PrintWriter(
			new BufferedWriter(
			new FileWriter("out.txt", true)))) {
	out2.println("the text");
} catch (IOException e) {
	e.printStackTrace();
}

Respuesta

Debido a que Writer debe cerrarse en cualquier caso (excepción o no excepción), close () debe colocarse en la cláusula finalmente.

Desde Java 7, podemos usar probar-con-recursos declaración.