JAVA04-manejo de excepciones

Las excepciones son algunos errores en el programa, pero no todos los errores son anormales y, a veces, se pueden evitar.
Por ejemplo, si a su código le falta un punto y coma, entonces el resultado es que el error es java.lang.Error; si usa System.out.println (11/0), entonces está dividiendo por 0 , Se lanzará una excepción de java.lang.ArithmeticException.
Hay muchas razones para las anomalías, que generalmente incluyen las siguientes categorías:

  • El usuario ingresó datos ilegales.
  • El archivo a abrir no existe.
  • La conexión se interrumpió durante la comunicación de red o la memoria JVM se desbordó.

Algunas de estas excepciones son causadas por errores del usuario, algunas son causadas por errores del programa y otras son causadas por errores físicos. -
Para entender el manejo de excepciones Java es cómo funciona, tenemos que comprender los siguientes tres tipos de excepciones:

  • Anomalías comprobables: las anomalías comprobables más representativas son las causadas por errores o problemas del usuario, que los programadores no pueden prever. Por ejemplo, cuando desea abrir un archivo que no existe, se produce una excepción que no se puede ignorar durante la compilación.
  • Excepciones en tiempo de ejecución: las excepciones en tiempo de ejecución son excepciones que los programadores pueden evitar. A diferencia de las excepciones marcadas, las excepciones de tiempo de ejecución se pueden ignorar en tiempo de compilación.
  • Errores: los errores no son excepciones, sino problemas que están fuera del control del programador. Los errores generalmente se ignoran en el código. Por ejemplo, cuando la pila se desborda, se produce un error y no se detectan durante la compilación.

Excepción de Java

Java tiene un mecanismo de manejo de excepciones incorporado que siempre usa excepciones para indicar errores.
Inserte la descripción de la imagen aquí
Se puede ver en la relación de herencia: Throwable es la raíz del sistema anormal, que hereda de Object. Throwable tiene dos sistemas: Error y Excepción. El error representa un error grave y el programa generalmente es inútil, por ejemplo:

  • OutOfMemoryError: sin memoria
  • NoClassDefFoundError: no se puede cargar una clase
  • StackOverflowError: el desbordamiento de pila
    y la excepción es un error de tiempo de ejecución, se puede detectar y manejar.
    Algunas excepciones son parte del procesamiento lógico de la aplicación y deben detectarse y manejarse. Por ejemplo:
  • NumberFormatException: error de formato de tipo numérico
  • FileNotFoundException: archivo no encontrado
  • SocketException: no se pudo leer la red

Algunas excepciones son causadas por una programación incorrecta de la lógica del programa, y ​​el programa en sí debe repararse. Por ejemplo:

  • NullPointerException: llama 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: 1. RuntimeException
y sus subclases;
2. Non-RuntimeException (incluyendo IOException, ReflectiveOperationException, etc.)

Java estipula:
Las excepciones que deben capturarse incluyen Exception y sus subclases, pero no RuntimeException y sus subclases. Este tipo de excepción se llama Excepción comprobada.
Las excepciones que no deben detectarse incluyen Error y sus subclases, RuntimeException y sus subclases.

La siguiente tabla enumera las excepciones no verificadas de Java.
Inserte la descripción de la imagen aquí
La siguiente tabla enumera las clases de excepción comprobadas de Java definidas en el paquete java.lang.
Inserte la descripción de la imagen aquí
La siguiente lista es los principales métodos de la clase Throwable:
Inserte la descripción de la imagen aquí

Captura de excepción

Para capturar excepciones, use la instrucción try ... catch, coloque el código donde la excepción puede ocurrir en try {...}, y luego use catch para capturar la excepción correspondiente y 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(); // 尝试使用用默认编码
        }
    }
}

El siguiente ejemplo declara una matriz con dos elementos: cuando el código intenta acceder al tercer elemento de la matriz, se genera una excepción.

// 文件名 : ExcepTest.java
import java.io.*;
public class ExcepTest{
 
   public static void main(String args[]){
      try{
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      }catch(ArrayIndexOutOfBoundsException e){
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

Un caso en el que un bloque de código de prueba es seguido por múltiples bloques de código de captura se denomina captura múltiple.
La sintaxis del bloque de captura múltiple es la siguiente:

try{
   // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}

finalmente declaración

El mecanismo try ... catch de Java también proporciona finalmente declaraciones, y finalmente los bloques de declaración están garantizados para ejecutarse con o sin errores.

public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
    } catch (UnsupportedEncodingException e) {
        System.out.println("Bad encoding");
    } catch (IOException e) {
        System.out.println("IO error");
    } finally {
        System.out.println("END");
    }
}

Tenga en cuenta que finalmente tiene varias características:
1. La declaración finally no es necesaria y puede escribirse o no,
2. finalmente siempre se ejecuta en último lugar.
Si no ocurre una excepción, ejecute el bloque de instrucción try {...} normalmente, luego ejecútelo finalmente. Si se produce una excepción, se interrumpe la ejecución del bloque de instrucciones try {…}, luego se omite la ejecución del bloque de instrucciones catch coincidente y finalmente se ejecuta la ejecución final.
Se puede ver que finalmente se utiliza para garantizar que se debe ejecutar algún código.
En algunos casos, no hay trampa, solo intenta ... finalmente estructura. Por ejemplo

void process(String file) throws IOException {
    try {
        ...
    } finally {
        System.out.println("END");
    }
}

Usar aserciones

La aserción es una forma de depurar un programa. En Java, use la palabra clave afirmar para implementar aserciones.

public static void main(String[] args) {
    double x = Math.abs(-123.45);
    assert x >= 0;
    System.out.println(x);
}

La afirmación afirmar x> = 0; es una afirmación, y se espera que la condición de afirmación x> = 0 sea verdadera. Si el resultado del cálculo es falso, la aserción falla y se lanza AssertionError.
Las características de las aserciones de Java son: AssertionError se lanzará cuando la aserción falle, lo que provocará que el programa salga. Por lo tanto, las aserciones no pueden usarse para errores de programa recuperables, y solo deben usarse para desarrollo y pruebas.

Registro de JDK

La biblioteca estándar de Java tiene un paquete de registro incorporado java.util.logging, que se puede usar directamente. Primero mira un ejemplo simple:

// logging
import java.util.logging.Level;
import java.util.logging.Logger;
public class Hello {
    public static void main(String[] args) {
        Logger logger = Logger.getGlobal();
        logger.info("start process...");
        logger.warning("memory is running out...");
        logger.fine("ignored.");
        logger.severe("process will be terminated...");
    }
}
运行上述代码,得到类似如下的输出:
Mar 02, 2019 6:32:13 PM Hello main
INFO: start process...
Mar 02, 2019 6:32:13 PM Hello main
WARNING: memory is running out...
Mar 02, 2019 6:32:13 PM Hello main
SEVERE: process will be terminated...

El registro de JDK define 7 niveles de registro, de severo a normal:

  • GRAVE
  • ADVERTENCIA
  • INFORMACIÓN
  • CONFIGURAR
  • MULTA
  • Más fino
  • FINEST
    porque el nivel predeterminado es INFO, por lo que no se imprimirán los registros por debajo del nivel INFO. La ventaja de utilizar el nivel de registro es que al ajustar el nivel, puede enmascarar muchas salidas de registro relacionadas con la depuración.
    El uso del registro incorporado en la biblioteca estándar de Java tiene las siguientes limitaciones: el
    sistema de registro lee el archivo de configuración y completa la inicialización cuando se inicia la JVM. Una vez que se inicia el método main (), la configuración no puede modificarse; la
    configuración no es conveniente, y los parámetros deben pasarse cuando se inicia la JVM.
-Djava.util.logging.config.file=<config-file-name>

Por lo tanto, el registro integrado en la biblioteca estándar de Java no se usa mucho.

Registro de Commons

Commons Logging es una biblioteca de registro de terceros, que es un módulo de registro creado por Apache.
La característica de Commons Logging es que se puede conectar a diferentes sistemas de registro, y el sistema de registro se puede especificar a través del archivo de configuración. De forma predeterminada, Commons Loggin busca automáticamente y utiliza Log4j (Log4j es otro sistema de registro popular). Si Log4j no se encuentra, entonces se utiliza el Registro JDK.
Debido a que Commons Logging es una biblioteca proporcionada por un tercero, primero debe descargarse. Después de descargarlo, descomprímalo, busque el archivo commons-logging-1.2.jar y coloque el código fuente de Java Main.java en un directorio.
El comando de compilación es el siguiente:

javac -cp commons-logging-1.2.jar Main.java

Para ejecutar este Main.class, use el comando java, también debe especificar el classpath, el comando es el siguiente:

java -cp .;commons-logging-1.2.jar Main

Para usar el registro de Commons, solo necesita tratar con dos clases, y solo hay dos pasos: el
primer paso es obtener la instancia de la clase Log a través de LogFactory; el segundo paso es usar el método de instancia Log para iniciar sesión.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Main {
    public static void main(String[] args) {
        Log log = LogFactory.getLog(Main.class);
        log.info("start...");
        log.warn("end.");
    }
}

Mar 02, 2019 7:15:31 PM Main main
INFO: start...
Mar 02, 2019 7:15:31 PM Main main
WARNING: end.

Commons Logging define 6 niveles de registro:

  • FATAL
  • ERROR
  • ADVERTENCIA
  • INFORMACIÓN
  • DEPURAR
  • El
    nivel predeterminado de TRACE es INFO.

Log4j

Log4j es un marco de registro muy popular, la última versión es 2.x.
Log4j es un sistema de registro diseñado por componentes, cuya arquitectura es aproximadamente la siguiente:

Cuando se utiliza Log4j para generar un registro, Log4j genera automáticamente el mismo registro en diferentes destinos a través de Appenders diferentes. Por ejemplo:

  • consola: salida a la pantalla;
  • archivo: salida a archivo;
  • socket: salida a una computadora remota a través de la red;
  • jdbc: Salida a la base de datos.
    En el proceso de salida de registros, Filter se usa para filtrar qué registros deben enviarse y cuáles no necesitan salir. Por ejemplo, solo se generan registros del nivel de ERROR.
    Finalmente, formatee la información de registro a través de Diseño, por ejemplo, agregue automáticamente la fecha, la hora, el nombre del método y otra información.
    Aunque la estructura anterior es complicada, cuando realmente la usamos, no necesitamos preocuparnos por la API Log4j, sino configurarla a través del archivo de configuración.
    Tomando la configuración XML como ejemplo, cuando usamos Log4j, colocamos un archivo log4j2.xml en el classpath para permitir que Log4j lea el archivo de configuración y genere el registro de acuerdo con nuestra configuración. El siguiente es un ejemplo de un archivo de configuración:
<?xml version="1.0" encoding="UTF-8"?><Configuration>
	<Properties>
        <!-- 定义日志格式 -->
		<Property name="log.pattern">%d{MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36}%n%msg%n%n</Property>
        <!-- 定义文件名变量 -->
		<Property name="file.err.filename">log/err.log</Property>
		<Property name="file.err.pattern">log/err.%i.log.gz</Property>
	</Properties>
    <!-- 定义Appender,即目的地 -->
	<Appenders>
        <!-- 定义输出到屏幕 -->
		<Console name="console" target="SYSTEM_OUT">
            <!-- 日志格式引用上面定义的log.pattern -->
			<PatternLayout pattern="${log.pattern}" />
		</Console>
        <!-- 定义输出到文件,文件名引用上面定义的file.err.filename -->
		<RollingFile name="err" bufferedIO="true" fileName="${file.err.filename}" filePattern="${file.err.pattern}">
			<PatternLayout pattern="${log.pattern}" />
			<Policies>
                <!-- 根据文件大小自动切割日志 -->
				<SizeBasedTriggeringPolicy size="1 MB" />
			</Policies>
            <!-- 保留最近10-->
			<DefaultRolloverStrategy max="10" />
		</RollingFile>
	</Appenders>
	<Loggers>
		<Root level="info">
            <!-- 对info级别的日志,输出到console -->
			<AppenderRef ref="console" level="info" />
            <!-- 对error级别的日志,输出到err,即上面定义的RollingFile -->
			<AppenderRef ref="err" level="error" />
		</Root>
	</Loggers></Configuration>

Aunque configurar Log4j es engorroso, una vez que se configura, es muy conveniente de usar. Para el archivo de configuración anterior, todos los registros de nivel INFO se enviarán automáticamente a la pantalla, y los registros de nivel ERROR se enviarán a la pantalla, así como al archivo. Y, una vez que el archivo de registro alcance el tamaño especificado (1 MB), Log4j cortará automáticamente el nuevo archivo de registro y retendrá hasta 10 copias.

No es suficiente tener un archivo de configuración, ya que Log4j también es una biblioteca de terceros, debe descargar Log4j, descomprimirlo y colocar los siguientes 3 paquetes jar en el classpath:

  • log4j-api-2.x.jar
  • log4j-core-2.x.jar
  • log4j-jcl-2.x.jar
    Debido a que Commons Logging descubrirá y usará Log4j automáticamente, por lo tanto, coloque el archivo commons-logging-1.2.jar descargado en la sección anterior en el classpath.
    Para imprimir el registro, solo escríbalo de acuerdo con Commons Logging, sin cambiar ningún código, puede obtener la salida del registro de Log4j, similar a:
03-03 12:09:45.880 [main] INFO  com.itranswarp.learnjava.MainStart process...
Publicado 23 artículos originales · elogiado 7 · 1002 visitas

Supongo que te gusta

Origin blog.csdn.net/qq_34356768/article/details/105082089
Recomendado
Clasificación