[Java] Manejo de excepciones en excepciones de Java

excepción java

En el proceso de ejecutar un programa de computadora, siempre ocurrirán varios errores.

Hay algunos errores cometidos por el usuario, por ejemplo, se espera que el usuario ingrese un inttipo de edad, pero la entrada del usuario es abc:

// 假设用户输入了abc:
String s = "abc";
int n = Integer.parseInt(s); // NumberFormatException!

Un programa quiere leer y escribir el contenido de un archivo, pero el usuario lo ha eliminado:

// 用户删除了该文件:
String t = readFile("C:\\abc.txt"); // FileNotFoundException!

También hay algunos errores que aparecen aleatoriamente y nunca se pueden evitar. Por ejemplo:

La red se desconecta repentinamente y el servidor remoto no se puede conectar;
la memoria se agota y el programa falla;
el usuario hace clic en "imprimir", pero no hay ninguna impresora;
...
Por lo tanto, un programa robusto debe lidiar con varios errores.

El llamado error es cuando el programa llama a una función, si falla, significa un error.

¿Cómo conoce la persona que llama la información sobre la falla de la llamada? Hay dos métodos:

Método 1: accedió a devolver un código de error.

Por ejemplo, para procesar un archivo, si devuelve 0, significa éxito, y si devuelve otros enteros, significa el código de error acordado:

int code = processFile("C:\\test.txt");
if (code == 0) {
    
    
    // ok:
} else {
    
    
    // error:
    switch (code) {
    
    
    case 1:
        // file not found:
    case 2:
        // no read permission:
    default:
        // unknown error:
    }
}

Debido al tipo de código de error utilizado int, es muy problemático manejarlo. Este enfoque es común en funciones C de bajo nivel.

Método 2: Proporcione un mecanismo de manejo de excepciones a nivel de lenguaje.

Java tiene un mecanismo de manejo de excepciones incorporado que siempre usa excepciones para indicar errores.

Exception es una clase, por lo que lleva información de tipo en sí misma. Las excepciones se pueden lanzar en cualquier lugar, pero solo se deben detectar en el nivel superior, de modo que se separen de las llamadas a métodos:

try {
    
    
    String s = processFile(C:\\test.txt”);
    // ok:
} catch (FileNotFoundException e) {
    
    
    // file not found:
} catch (SecurityException e) {
    
    
    // no read permission:
} catch (IOException e) {
    
    
    // io error:
} catch (Exception e) {
    
    
    // other error:
}

Debido a que la excepción de Java es una clase, su relación de herencia es la siguiente:

inserte la descripción de la imagen aquí

Se puede ver a partir de la relación de herencia: Throwablees la raíz del sistema anormal, del cual hereda Object. ThrowableHay dos sistemas: Errory Exception, Errorque representan errores graves, para los cuales el programa generalmente no puede hacer nada, por ejemplo:

  • OutOfMemoryError: Sin memoria
  • NoClassDefFoundError: no se puede cargar unClass
  • StackOverflowError: el desbordamiento de pila Exceptiones un error de tiempo de ejecución que se puede detectar y manejar.

Ciertas excepciones son parte del procesamiento de la lógica de la aplicación y deben detectarse y manejarse. Por ejemplo:

  • NumberFormatException: formato incorrecto para el tipo numérico
  • FileNotFoundException: archivo no encontrado
  • SocketException: no se pudo leer la red

También hay algunas excepciones causadas por una lógica de programa incorrecta, y el propio programa debe repararse. Por ejemplo:

  • NullPointerException: llamar a un método o campo en un objeto nulo
  • IndexOutOfBoundsException: índice de matriz fuera de los límites

La excepción se divide en dos categorías:

  • RuntimeException y sus subclases;
  • Non-RuntimeException (incluyendo IOException, ReflectiveOperationException, etc.)

Java estipula:

Las excepciones que deben capturarse, incluyendo Exceptiony excluyendo RuntimeExceptionsus subclases, se denominan excepciones de este tipo Checked Exception.

Excepciones que no necesitan capturarse, incluidas Errorsus subclases RuntimeExceptiony sus subclases.

Nota: el compilador RuntimeExceptionno establece requisitos de captura obligatorios para sus subclases, lo que no significa que la aplicación en sí no deba capturar y procesar archivos RuntimeException. Si es necesario capturarlo depende del análisis específico de problemas específicos.

excepción de captura

Use declaraciones para capturar excepciones try...catch, coloque el código que puede causar excepciones try {...}y luego use catchel catch correspondiente Exceptiony sus subclases:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) {
    
    
        try {
    
    
            // 用指定编码转换String为byte[]:
            return s.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
    
    
            // 如果系统不支持GBK编码,会捕获到UnsupportedEncodingException:
            System.out.println(e); // 打印异常信息
            return s.getBytes(); // 尝试使用用默认编码
        }
    }
}

Si no lo detectamos UnsupportedEncodingException, habrá un problema de falla de compilación:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) {
    
    
        return s.getBytes("GBK");
    }
}

El compilador reportará un error, el mensaje de error es similar a: unreported exception UnsupportedEncodingException; must be caught or declared to be thrown, y precisamente se señala que la sentencia que hay que capturar es return s.getBytes("GBK");. Es decir, UnsupportedEncodingExceptionasí Checked Exception, tiene que ser atrapado.

Esto se debe a que la definición del método String.getBytes(String) es:

public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
    
    
    ...
}

Cuando se define el método, utilice throws Xxx para indicar el tipo de excepción que puede generar el método. Al llamar, la persona que llama debe detectar estas excepciones a la fuerza, de lo contrario, el compilador informará un error.

En el método toGBK(), debido a que String.getBytes(String)se llama al método, debe capturarse UnsupportedEncodingException. Tampoco podemos capturarlo, pero usarlo en la definición del método para throwsindicar que toGBK()el método puede arrojar UnsupportedEncodingException, de modo que toGBK()el método pueda pasar la verificación del compilador:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
    
    
        return s.getBytes("GBK");
    }
}

El código anterior aún obtendrá errores de compilación, pero esta vez, el compilador no genera return s.getBytes("GBK");el problema de llamar, sino byte[] bs = toGBK("中文");. Porque en el método main(), la llamada toGBK()no captura lo que declara que puede arrojar UnsupportedEncodingException.

La solución es capturar la excepción y manejarla en el método main():

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            byte[] bs = toGBK("中文");
            System.out.println(Arrays.toString(bs));
        } catch (UnsupportedEncodingException e) {
    
    
            System.out.println(e);
        }
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
    
    
        // 用指定编码转换String为byte[]:
        return s.getBytes("GBK");
    }
}

Se puede ver que siempre que sea declarado por un método Checked Exception, debe capturarse en un nivel de llamada superior si no se captura en el nivel de llamada. Todas las excepciones no capturadas deben eventualmente main()ser capturadas en el método, y no habrá omisión de intento. Esto está garantizado por el compilador. main()El método es también la última Exceptionoportunidad de atrapar.

Si es un código de prueba, el método de escritura anterior es un poco problemático. Si no desea escribir ningún código de prueba, puede main()definir directamente el método como throws Exception:

// try...catch
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
    
    
    public static void main(String[] args) throws Exception {
    
    
        byte[] bs = toGBK("中文");
        System.out.println(Arrays.toString(bs));
    }

    static byte[] toGBK(String s) throws UnsupportedEncodingException {
    
    
        // 用指定编码转换String为byte[]:
        return s.getBytes("GBK");
    }
}

Debido a que main()el método declara que puede arrojar Exception, también declara que puede arrojar todo Exception, por lo que no es necesario capturarlo internamente. El precio es que una vez que ocurre una excepción, el programa saldrá inmediatamente.

También hay algunos zapatos para niños a los que les gusta toGBK()"digerir" las anomalías internamente:

static byte[] toGBK(String s) {
    
    
    try {
    
    
        return s.getBytes("GBK");
    } catch (UnsupportedEncodingException e) {
    
    
        // 什么也不干
    }
    return null;
    ```
这种捕获后不处理的方式是非常不好的,即使真的什么也做不了,也要先把异常记录下来:
```java
static byte[] toGBK(String s) {
    
    
    try {
    
    
        return s.getBytes("GBK");
    } catch (UnsupportedEncodingException e) {
    
    
        // 先记下来再说:
        e.printStackTrace();
    }
    return null;

Todas las excepciones pueden llamar printStackTrace()al método para imprimir la pila de excepciones, que es un método simple y útil para imprimir excepciones rápidamente.

resumen

Java usa excepciones para indicar errores y al try ... catchcapturar excepciones;

Las excepciones de Java son de clase y Throwablese heredan de;

Errores un error grave que no necesita detectarse Exceptiony es un error manejable que debe detectarse;

RuntimeExceptionNo hay captura obligatoria, RuntimeException(Checked Exception)captura obligatoria o declaración de lanzamiento;

No se recomienda capturar una excepción pero no hacer nada.

Supongo que te gusta

Origin blog.csdn.net/ihero/article/details/132148589
Recomendado
Clasificación