Análisis del mecanismo de excepción de Java: detección de errores en la programación para garantizar la estabilidad del código

En el trabajo, la situación que encuentra el programa no puede ser perfecta. Por ejemplo: el programa quiere abrir un archivo determinado, el archivo puede no existir o el formato del archivo es incorrecto; el programa se está ejecutando, pero la memoria o el disco duro pueden estar llenos, etc.

Durante la ejecución de un programa de software, es muy probable que se presenten los problemas que acabamos de mencionar. Los llamamos excepciones. El inglés es: Exception, que significa excepciones. Al encontrar estas excepciones, o llamadas excepciones, ¿cómo podemos hacer que el programa escrito las maneje razonablemente y salga de manera segura sin que el programa se bloquee? Permitame presentar:

⭐ Mecanismo de excepción

Si queremos copiar un archivo, en ausencia de un mecanismo de excepción, debemos considerar varias excepciones, el pseudocódigo
es el siguiente:

[Ejemplo] Pseudocódigo: Hay dos desventajas de usar if para manejar varias situaciones que pueden ocurrir en el programa :
inserte la descripción de la imagen aquí

  1. ¡Ponga el código lógico y el código de manejo de errores juntos!

  2. ¡Las excepciones que los propios programadores deben considerar son más complicadas y los requisitos para los propios programadores son más altos!
    Para la situación anterior, si es manejada por el mecanismo de excepción de Java, la comparación es la siguiente:
    inserte la descripción de la imagen aquí

     异常机制本质
     当程序出现异常,程序安全的退出、处理完后继续执行的机制
    

⭐ El concepto de Excepción

Las anomalías se refieren a fenómenos anormales que ocurren durante la ejecución del programa, como que el divisor es cero, el archivo que se procesará no existe y el subíndice de la matriz está fuera de los límites.

En el mecanismo de manejo de excepciones de Java, se introducen muchas clases utilizadas para describir y manejar excepciones, llamadas clases de excepción. La definición de clase de excepción contiene la información de este tipo de excepción y el método para manejar la excepción.

Comencemos mirando nuestro primer objeto de excepción y analicemos cómo funciona el mecanismo de excepción.

[Ejemplo] Análisis anormal

public class Test {
    
    
 public static void main(String[] args) {
    
    
 System.out.println("111");
 int a = 1/0;
 System.out.println("222");
 }
}

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

Según el resultado, podemos ver que ocurrió una excepción al ejecutar "1/0", el programa terminó y no se ejecutó la acción posterior de imprimir "222".

Si usamos try-catch para manejarlo, el programa puede manejarlo normalmente cuando encuentra una excepción.Después de que se completa el procesamiento, el programa continúa ejecutándose:

public class Test {
    
    
 public static void main(String[] args) {
    
    
 System.out.println("111");
 try {
    
    
 int a = 1/0;
 } catch (Exception e) {
    
    
 e.printStackTrace();
 }
 System.out.println("222");
 }
}

Los resultados de la ejecución son los siguientes:
inserte la descripción de la imagen aquí

El programa aún encuentra una excepción durante la ejecución de "1/0" y luego el procesamiento de intento de captura. Una vez completado el procesamiento, el programa continúa ejecutándose y se imprime el contenido de "222".

Java maneja las excepciones de forma orientada a objetos. Proceso:

⭐	抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给 JRE。
⭐	捕获异常:JRE 得到该异常后,寻找相应的代码来处理该异常。JRE 在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。

⭐ Clasificación de excepciones

Muchas clases de excepción se definen en Java, que corresponden a varios eventos de excepción posibles, y todos los objetos de excepción se derivan de una instancia de la clase Throwable. Si la clase de excepción integrada no puede satisfacer sus necesidades, también puede crear su propia clase de excepción.

Java clasifica las excepciones. Los diferentes tipos de excepciones están representados por diferentes clases de Java. La clase raíz de todas las excepciones es java.lang.Throwable, y dos subclases se derivan de Throwable: Error y Exception. La jerarquía de las clases de excepción de Java se muestra en la figura:
inserte la descripción de la imagen aquí

Error

Error es un error que el programa no puede manejar, lo que indica un problema grave al ejecutar la aplicación. La mayoría de los errores no están relacionados con las acciones realizadas por el autor del código, sino que representan problemas con la JVM (Java Virtual Machine) cuando se ejecuta el código. Por ejemplo, error de operación de máquina virtual Java (Virtual MachineError), cuando la JVM ya no tiene los recursos de memoria necesarios para continuar con la operación, aparecerá OutOfMemoryError. Cuando ocurren estas excepciones, la máquina virtual de Java (JVM) generalmente elige el subproceso para terminar.

El error indica que la JVM del sistema ha estado en un estado de bloqueo irrecuperable.
inserte la descripción de la imagen aquí

Error 与 Exception 的区别
⭐	我开着车走在路上,一头猪冲在路中间,我刹车。这叫一个异常。
⭐	我开着车在路上,发动机坏了,我停车,这叫错误。系统处于不可恢复的崩溃状态。发动机什么时候坏?我们普通司机能管吗?不能。发动机什么时候坏是汽车厂发动机制造商的事。

Excepción

Exception es una excepción que el propio programa puede manejar.

La clase Exception es la clase principal de todas las clases de excepción y sus subclases corresponden a varios eventos de excepción posibles. En general, las excepciones de Java se pueden dividir en:

⭐	RuntimeException 运行时异常
⭐	CheckedException 已检查异常

Excepción de tiempo de ejecución RuntimeException

Las excepciones derivadas de RuntimeException, como la división por 0, el subíndice de matriz fuera de los límites, el puntero nulo, etc., se generan con frecuencia y son difíciles de manejar. Si se declaran o capturan explícitamente, tendrán un gran impacto en la legibilidad y el funcionamiento del programa. eficiencia. Por lo tanto, el sistema los detecta automáticamente y los entrega al controlador de excepciones predeterminado.

El compilador no maneja RuntimeException, los programadores deben agregar "procesamiento lógico para evitar estas excepciones".

[Ejemplo] ArithmeticException: intento de dividir por 0

public class Test3 {
    
    
	public static void main(String[ ] args) {
    
    
	int b=0;
	System.out.println(1/b);
	}
}

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

Para resolver la excepción anterior, debe modificar el código:

public class Test3 {
    
    
	public static void main(String[ ] args) {
    
    
		int b=0;
		if(b!=0){
    
    
		System.out.println(1/b);
		}
	}
}

[Ejemplo] Excepción NullPointerException

public class Test4 {
    
    
	public static void main(String[ ] args) {
    
    
		String str=null;
		System.out.println(str.charAt(0));
	}
}

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

Para resolver la excepción del puntero nulo, generalmente se aumenta el juicio no nulo:

public class Test4 {
    
    
	public static void main(String[ ] args) {
    
    
		String str=null;
		if(str!=null){
    
    
		System.out.println(str.charAt(0));
		}
	}
}

[Ejemplo] Excepción ClassCastException

class Animal{
    
    
}
class Dog extends Animal{
    
    
}
class Cat extends Animal{
    
    
}
public class Test5 {
    
    
	public static void main(String[ ] args) {
    
    
		Animal a=new Dog();
		Cat c=(Cat)a;
	}
}

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

Manera típica de resolver ClassCastException:

public class Test5 {
    
    
	public static void main(String[ ] args) {
    
    
		Animal a = new Dog();
		if (a instanceof Cat) {
    
    
		Cat c = (Cat) a;
		}
	}
}

[Ejemplo] Excepción ArrayIndexOutOfBoundsException

public class Test6 {
    
    
	public static void main(String[ ] args) {
    
    
		int[ ] arr = new int[5];
		System.out.println(arr[5]);
	}
}

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

La forma de resolver la excepción fuera de los límites del índice de matriz es aumentar el juicio sobre el límite:

	public class Test6 {
    
    
		public static void main(String[ ] args) {
    
    
			int[ ] arr = new int[5];
			int a = 5;
			if (a < arr.length) {
    
    
			System.out.println(arr[a]);
		}
	}
}

[Ejemplo] Excepción NumberFormatException

	public class Test7 {
    
    
		public static void main(String[ ] args) {
    
    
		String str = "1234abcf";
		System.out.println(Integer.parseInt(str));
	}
}

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

Para resolver el formato anormal de números, puede introducir expresiones regulares para juzgar si se trata de un número:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
	public class Test7 {
    
    
		public static void main(String[ ] args) {
    
    
			String str = "1234abcf";
			Pattern p = Pattern.compile("^\\d+$");
			Matcher m = p.matcher(str);
			if (m.matches()) {
    
     // 如果 str 匹配代表数字的正则表达式,才会转换
			System.out.println(Integer.parseInt(str));
		}
	}
}

⭐ Excepción comprobada CheckedException

inserte la descripción de la imagen aquí

CheckedException debe manejarse en el momento de la compilación; de lo contrario, no se podrá compilar. como muestra la imagen.
inserte la descripción de la imagen aquí

Hay dos formas de manejar las excepciones CheckedException:

⭐	使用“try/catch”捕获异常
⭐	使用“throws”声明异常。

⭐ Uno de los métodos de manejo de excepciones: excepción de captura

inserte la descripción de la imagen aquí

intentar:

La declaración de prueba especifica una pieza de código que es el alcance de la captura y el procesamiento de excepciones. Durante la ejecución, cuando cualquier instrucción genere una excepción, se omitirá el siguiente código de la instrucción. Uno o varios tipos de objetos de excepción pueden generarse y lanzarse en el código, y la instrucción catch detrás debe manejar estas excepciones en consecuencia.

Una declaración de prueba debe ir acompañada de al menos un bloque de declaración de captura o un bloque de declaración de finalización.

注意事项
⭐	当异常处理的代码执行结束以后,不会回到 try 语句去执行尚未执行的代码。

atrapar:

⭐	每个 try 语句块可以伴随一个或多个 catch 语句,用于处理可能产生的不同类型的异常对象。
⭐	catch 捕获异常时的捕获顺序:
⭐	如果异常类之间有继承关系,先捕获子类异常再捕获父类异常。

finalmente:

⭐	不管是否发生了异常,都必须要执行。
⭐	通常在 finally 中关闭已打开的资源,比如:关闭文件流、释放数据库连接等。

Análisis detallado del proceso de ejecución del bloque de instrucciones try-catch-finally:

El programa primero ejecuta un bloque de declaraciones de prueba donde puede ocurrir una excepción. Si no hay una excepción en la declaración de prueba, saltará al bloque de declaración finalmente después de la ejecución; si hay una excepción en la declaración de prueba, interrumpirá la ejecución y saltará al bloque de declaración de captura correspondiente para procesar de acuerdo con el tipo de excepción que se produzca. Puede haber múltiples bloques de instrucciones catch, cada uno de los cuales captura diferentes tipos de excepciones. Después de ejecutar el bloque de instrucciones catch, el programa continuará ejecutando el bloque de instrucciones finalmente. La declaración final es opcional. Si está presente, la declaración final se ejecutará independientemente de si se produce una excepción.

[Ejemplo] Código típico para el manejo de excepciones (excepción de captura)

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test8 {
    
    
	public static void main(String[ ] args) {
    
    
		FileReader reader = null;
		try {
    
    
		reader = new FileReader("d:/a.txt");
		char c = (char) reader.read();
		char c2 = (char) reader.read();
	System.out.println("" + c + c2);
		} catch (FileNotFoundException e) {
    
    
		e.printStackTrace();
		} catch (IOException e) {
    
    
		e.printStackTrace();
		} finally {
    
    
		try {
    
    
		if (reader != null) {
    
    
		reader.close();
			}
		} catch (Exception e) {
    
    
		e.printStackTrace();
			}
		}
	}
}

En entornos de desarrollo comunes, las teclas de método abreviado para los bloques de código try-catch se agregan automáticamente:

⭐	将需要处理异常的代码选中。
⭐	IDEA 中,使用:ctrl+alt+t
⭐	eclipse 中,使用:ctrl+shift+z

⭐ La segunda forma de manejar excepciones: declarar excepciones (cláusula de lanzamientos)

inserte la descripción de la imagen aquí

⭐	CheckedException 产生时,不一定立刻处理它,可以把异常 throws,由调用者处理。
⭐	一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常。

[Ejemplo] Código típico para el manejo de excepciones (declarar lanzamientos de excepción)

package oldwang;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Test9 {
    
    
 public static void main(String[ ] args) {
    
    
 try {
    
    
 readFile("joke.txt");
 } catch (FileNotFoundException e) {
    
    
 System.out.println("所需文件不存在!");
 } catch (IOException e) {
    
    
 System.out.println("文件读写错误!");
 }
 }
 public static void readFile(String fileName) throws FileNotFoundException,IOException {
    
    
 FileReader in = new FileReader(fileName);
 int tem = 0;
 try {
    
    
 tem = in.read();
 while (tem != -1) {
    
    
 System.out.print((char) tem);
 tem = in.read();
 }
 } finally {
    
    
 if(in!=null) {
    
    
 in.close();
 }
 }
 }
}

Precauciones

⭐	方法重写中声明异常原则:子类重写父类方法时,如果父类方法有声明异常,那么子类声明的异常范围不能超过父类声明的范围。

try-with-resource cierra automáticamente los recursos de la interfaz AutoClosable

En JAVA, el mecanismo de recolección de basura de la JVM puede reciclar automáticamente los recursos internos, lo que brinda una gran comodidad a los desarrolladores. Sin embargo, las referencias de JVM a recursos externos (recursos que llaman al sistema operativo subyacente), como conexiones de base de datos, conexiones de red y flujos de E/S de entrada y salida, no se pueden reciclar automáticamente. Estas conexiones deben cerrarse manualmente, de lo contrario, provocarán una fuga de recursos externos, un desbordamiento del grupo de conexiones y una ocupación anormal de archivos.

Después de JDK7, se agregó "probar con recursos". Puede cerrar automáticamente la clase que implementa la interfaz AutoClosable, y la clase implementadora necesita implementar el método close(). La "sentencia try-with-resources
" simplifica try-catch-finally a try-catch, que en realidad es un tipo de azúcar sintáctico, y aún se convertirá en una declaración try-catch-finally en tiempo de compilación.

package oldwang;
import java.io.FileReader;
public class Test8 {
    
    
 public static void main(String[ ] args) {
    
    
 try(FileReader reader = new FileReader("d:/a.txt");) {
    
    
 char c = (char) reader.read();
 char c2 = (char) reader.read();
 System.out.println("" + c + c2);
 } catch (Exception e) {
    
    
 e.printStackTrace();
 }
 }
}

excepción personalizada

⭐	在程序中,可能会遇到 JDK 提供的任何标准异常类都无法充分描述清楚我们想要表达的问题,这种情况下可以创建自己的异常类,即自定义异常类。
⭐	自定义异常类只需从 Exception 类或者它的子类派生一个子类即可。
⭐	自定义异常类如果继承 Exception 类,则为 CheckedException 异常,必须对其进行处理;如果不想处理,可以让自定义异常类继承运行时异常RuntimeException 类。
⭐	习惯上,自定义异常类应该包含 2 个构造器:一个是默认的构造器,另一个是带有详细信息的构造器。

[Ejemplo] Clase de excepción personalizada

/**IllegalAgeException:非法年龄异常,继承 Exception 类*/
public class IllegalAgeException extends Exception {
    
    
//默认构造器
public IllegalAgeException() {
    
    
}
//带有详细信息的构造器,信息存储在 message 中
public IllegalAgeException(String message) {
    
    
super(message);
}
}

[Ejemplo] Uso de clases de excepción personalizadas

class Person {
    
    
private String name;
private int age;
public void setName(String name) {
    
    
this.name = name;
}
public void setAge(int age) throws IllegalAgeException {
    
    
if (age < 0) {
    
    
throw new IllegalAgeException("人的年龄不应该为负数");
 }
this.age = age;
}
public String toString() {
    
    
return "name is " + name + " and age is " + age;
}
}
public class TestMyException {
    
    
public static void main(String[ ] args) {
    
    
Person p = new Person();
try {
    
    
p.setName("Lincoln");
p.setAge(-1);
} catch (IllegalAgeException e) {
    
    
e.printStackTrace();
}
System.out.println(p);
}
}

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

Recomendaciones para usar el mecanismo de excepción

⭐	要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下。
⭐	处理异常不可以代替简单测试---只在异常情况下使用异常机制。
⭐	不要进行小粒度的异常处理---应该将整个任务包装在一个 try 语句块中。
⭐	异常往往在高层处理 。

⭐ Cómo usar Baidu para resolver problemas anormales

inserte la descripción de la imagen aquí

En el aprendizaje y el desarrollo normales, a menudo encontramos varias excepciones. Cuando encuentre una excepción, debe seguir los siguientes cuatro pasos para resolverla:

⭐	细心查看异常信息,确定异常种类和相关 Java 代码行号
⭐	确定上下文相关的一些关键词信息(疑难问题,需要)。拷贝异常信息到百度,查看相关帖子,寻找解决思路;
⭐	前两步无法搞定,再问同学/老师或同事;
⭐	前三步无法搞定,请示领导。

Muchos estudiantes entran en pánico tan pronto como encuentran una anomalía e inmediatamente comienzan a pedir ayuda a otros, pero no saben que hay dos desventajas importantes al hacerlo. Primero, faltarle demasiado el respeto a los demás y tratarlos como coolies. Segundo, pierdes la oportunidad de mejorarte a ti mismo Resolver una anomalía por ti mismo significa tener la capacidad de resolver una clase de anomalías. Resolver una clase de anomalías puede mejorar enormemente las habilidades de uno.
No tenga miedo de dedicar tiempo a resolver problemas y no sienta que resolver problemas es una pérdida de tiempo. En el proceso de resolver el problema, también estás pensando.

Súper búsqueda de Baidu:

La clave para una buena búsqueda en Baidu/Google es confirmar las palabras clave y hacer las preguntas correctamente.

⭐	寻找问题本身的关键词(名词)
⭐	寻找问题上下文的关键词(名词)
⭐	尽量细致的描述问题,开始搜索
⭐	如果没找到,慢慢减少关键词,扩大搜索范围。

⭐ Depuración de depuración de IDEA

inserte la descripción de la imagen aquí

En el corazón de la depuración se encuentran los puntos de interrupción. Cuando la ejecución del programa alcanza el punto de interrupción, suspende temporalmente y detiene la ejecución. Al igual que ver un video y presionar detener, podemos ver cada detalle de la parada en detalle.

punto de interrupción

El programa se ejecuta aquí, se suspende temporalmente y deja de ejecutarse. Podemos observar el funcionamiento del programa en detalle en este momento, para hacer más juicios.

  1. Establezca un punto de interrupción:
    (1) Haga clic detrás del número de línea para agregar un punto de interrupción
    inserte la descripción de la imagen aquí

(2) Haga clic nuevamente en el punto de interrupción para cancelar el punto de interrupción

Entrar en la vista de depuración

Podemos ingresar a la vista de depuración de las siguientes tres maneras:
(1) Haga clic en el botón en la barra de herramientas:inserte la descripción de la imagen aquí

(2) Haga clic derecho en el área de edición, haga clic en: depurar

Después de ingresar a la vista de depuración, el diseño es el siguiente:
inserte la descripción de la imagen aquí

A la izquierda está el "marco de navegación":
el depurador enumera los métodos que el subproceso actual está ejecutando en el punto de interrupción, y cada método corresponde a un "marco de pila". El superior es el método donde se encuentra el punto de interrupción actual.

Área de observación de valor variable:

El depurador enumera los valores de las variables asociadas con el método en el punto de interrupción. Podemos usarlo para ver los cambios en el valor de las variables.

Área de operación de depuración
inserte la descripción de la imagen aquí

Usamos los botones en la figura anterior para realizar operaciones de depuración, y sus significados son los siguientes:
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/Wwd631255/article/details/131194660
Recomendado
Clasificación