"Hola, Amigo. Vamos a tener una lección muy interesante hoy. Te voy a hablar sobre las excepciones. Las excepciones son un mecanismo especial que nos permite manejar errores en el programa. Aquí hay algunos ejemplos de errores que pueden ocurrir. en un programa:

1. El programa puede intentar escribir un archivo cuando el disco duro está completamente lleno.

2. El programa puede intentar llamar a un método en una variable que almacena una referencia nula.

3. El programa puede intentar dividir un número por 0".

Todas estas acciones dan como resultado errores. Normalmente, el resultado es que el programa termina inmediatamente, ya que no tiene sentido seguir ejecutando código en este caso.

"¿Por qué?"

"¿Tiene sentido seguir girando una rueda si el automóvil se ha salido de la carretera y se está cayendo por un precipicio?"

"¿Debería dejar de ejecutarse el programa, entonces?"

"Sí. Al menos, esto es lo que solía suceder. Cualquier error hacía que el programa terminara".

"Ese es un enfoque muy inteligente".

"¿Pero no sería mejor intentar y continuar ejecutando el programa?"

"Sí. Supongamos que escribiste una gran cantidad de texto en Word y lo guardaste. ¿Qué pasa si la operación de guardar falla, pero el programa te hace creer que todo está bien? Y sigues escribiendo. Eso sería estúpido, ¿no es así?" ¿él?"

"Sí."

"Luego, a los programadores se les ocurrió una solución interesante: cada función devolvería el estado de su trabajo. 0 significaba que funcionaba como se esperaba. Cualquier otro valor significaría que se produjo algún error y el valor de retorno fue un código de error".

"Sin embargo, ese enfoque también tiene sus deficiencias. Después de cada (!) llamada de función, debe verificar el código de retorno (número). En primer lugar, esto es un inconveniente: el código de manejo de errores rara vez se ejecuta, pero debe incluirse en todas partes. En segundo lugar, las funciones a menudo devuelven valores diferentes: ¿qué se supone que debes hacer con ellos?

"Claro. Yo también pensé en eso."

"Luego, llegó un futuro brillante en forma de excepciones y un mecanismo de manejo de errores. Así es como funciona:

1. Cuando ocurre un error, la máquina Java crea un objeto especial, una excepción, donde guarda toda la información del error. Hay diferentes excepciones para diferentes errores.

2. Una excepción hace que el programa salga inmediatamente de la función actual y de la función siguiente, y así sucesivamente, hasta que salga del método principal. Entonces el programa termina. Los programadores también pueden decir que la máquina Java 'desenrolla la pila de llamadas'".

"Pero dijiste que el programa no siempre termina".

"Sí, porque hay una forma de detectar una excepción. Podemos escribir un código especial en el lugar correcto para detectar las excepciones que nos interesan y hacer algo con ellas. Esto es algo importante".

"Para ayudarnos a hacer esto, hay una construcción especial de intento y captura . Así es como funciona:"

Ejemplo de un programa que atrapa una excepción (división por 0) y sigue funcionando.
public class ExceptionExample2
{
    public static void main(String[] args)
    {
        System.out.println("Program starts");

        try
        {
            System.out.println("Before calling method1");
            method1();
            System.out.println("After calling method1. This will never be shown");
        }
        catch (Exception e)
        {
           System.out.println("Exception has been caught");
        }

        System.out.println("Program is still running");
    }

    public static void method1()
    {
        int a = 100;
        int b = 0;
        System.out.println(a / b);
    }
}
Salida de pantalla:

Program starts
Before method1 calling
Exception has been caught
Program is still running

"Pero, ¿por qué no se muestra 'Después de llamar al método 1. Esto nunca se mostrará' en la pantalla?"

"Me alegro de que haya preguntado. En la línea 25, dividimos por 0, lo que genera un error: una excepción. La máquina Java crea un objeto ArithmeticException con información sobre el error. El objeto es la excepción".

"La excepción ocurre dentro del method1método. Esto hace que el método finalice inmediatamente. Causaría que el método principal finalice si no fuera por el bloque try-catch ".

"Si ocurre una excepción dentro de un bloque de prueba, se captura en el bloque de captura. El resto del código en el bloque de prueba no se ejecutará. En su lugar, el bloque de captura comenzará a ejecutarse " .

"No lo entiendo".

"En otras palabras, el código funciona así:

1. Si ocurre una excepción dentro de un bloque try , el código deja de ejecutarse donde ocurrió la excepción y comienza a ejecutarse el bloque catch .

2. Si no se produce ninguna excepción, el bloque try se ejecuta hasta el final y el bloque catch no se ejecuta. "

"¿Eh?"

"Imagínese que después de cada llamada al método verificamos si el método se devolvió normalmente o si se terminó abruptamente como resultado de una excepción. Si hay una excepción, nos movemos para ejecutar el bloque catch (si lo hay) para atrapar la excepción. Si no hay un bloque catch, terminamos el método actual y el método que nos llamó realiza la misma verificación".

"Creo que lo tengo ahora".

"Excelente."

"¿Qué significa 'Excepción' dentro de la instrucción catch?"

" Todas las excepciones son clases que heredan la clase Exception. Podemos capturar una excepción en particular especificando la clase de excepción en el bloque catch , o podemos capturar todas las excepciones especificando su clase principal común – Exception. Entonces podemos obtener todos los errores necesarios información de la variable e (almacena una referencia al objeto de excepción)."

"¡Genial! Si ocurren diferentes excepciones en mi método, ¿puedo procesarlas de manera diferente?"

"No solo puedes, sino que debes hacerlo. Puedes hacerlo así:"

Ejemplo:
public class ExceptionExample2
{
    public static void main(String[] args)
    {
        System.out.println("Program starts");

        try
        {
            System.out.println("Before calling method1");
            method1();
            System.out.println("After calling method1. This will never be shown");
        }
        catch (NullPointerException e)
        {
           System.out.println("Null reference. Exception has been caught");
        }
        catch (ArithmeticException e)
        {
            System.out.println("Division by zero. Exception has been caught");
        }
        catch (Exception e)
        {
            System.out.println("Any other errors. Exception has been caught");
        }

        System.out.println("Program is still running");
    }

    public static void method1()
    {
        int a = 100;
        int b = 0;
        System.out.println(a / b);
    }
}

"El bloque try se puede emparejar con varios bloques catch , cada uno de los cuales detectará los tipos de excepciones especificados".

"Creo que lo entiendo. No puedo escribir esto yo mismo todavía, pero si lo encuentro en código, no me asustaré".