¿Cuál es el papel del mecanismo de excepción en Java?
ARCHIVO * fp;
fp = fopen (nombre de archivo, "rw");
if (fp == NULL){
printf ("no se puede abrir el archivo\n");
salir (0);
salir( 0) ;
}
En este programa, el párrafo en la declaración condicional if se usa para manejar la situación en la que el archivo especificado no se encuentra o no se puede abrir correctamente debido a otras razones. Sin embargo, si se encuentra con un programador con un débil sentido de responsabilidad, puede pensar que la posibilidad de no encontrar el archivo es muy pequeña, o puede olvidarse de lidiar con esta situación porque está concentrado en la implementación de la función del programa. El programa también se compilará correctamente y, en general, no habrá problemas. Sin embargo, el programa definitivamente no es lo suficientemente robusto. Si ocurre un error en el programa, será difícil para el programador descubrir dónde está el error. Hay muchos ejemplos de esto en C y en la mayoría de los demás lenguajes de alto nivel.
Es decir, una función puede usarse de una manera que no logra su propósito previsto, incluso aunque en el entorno específico en el que se usa el programa, la probabilidad de que ocurra tal excepción sea solo de una en 10.000. La forma habitual de lidiar con esta situación es que el programador que necesita usar la función debe comprender completamente las razones que pueden causar que la función no se ejecute correctamente y luego agregar declaraciones condicionales apropiadas para manejarla. Más adelante se dará un ejemplo.
El mecanismo de excepción de Java proporciona a los programadores una forma muy sencilla y flexible de abordar estos problemas. Mientras que otros lenguajes de alto nivel se centran en permitir que el usuario de una función preste atención a las excepciones que pueden surgir en la función, Java permite que el diseñador de un método (el equivalente de una función en Java, llamado método) haga el trabajo. . La conveniencia que esto trae a los usuarios del método es que al utilizar el método, no se olvidarán de manejar posibles excepciones por falta de responsabilidad o trabajo inadecuado. El problema es que cuando usas un método que podría generar una excepción, no puedes simplemente ignorarlo, tienes que manejarlo. Es decir, al igual que el segmento del programa C anterior, si olvida el bloque if, el programa puede incluso pasar al jefe profano, pero cuando se usa Java para completar esta función, siempre que el método utilizado utilice el mecanismo de "excepción", si no hay control sobre la posible El método "Excepción" lo maneja en consecuencia y el compilador de Java no lo dejará pasar.
1. Organización de las "Clase de Excepción"
Los métodos de clase que generan excepciones en el sistema Java se organizan en "Clases de Excepción" (también existen clases de Error, que no están dentro del alcance de este artículo)), este método y sus "clases de excepción" asociadas están asociadas con la palabra clave throws, y estas clases deben ser subclases de la clase Exception. Cualquier clase de desarrollo propio que tenga un método que pueda generar una excepción también puede organizar la excepción en una "clase de excepción", pero la "clase de excepción" también debe ser una subclase de Exception o una gran clase de Exception, y así sucesivamente.
Ejemplo 1:
/*isLegal comprueba si los datos son legales. Cuando >0, se considera legal y se devuelve un valor legal. De lo contrario, se considera ilegal y el valor se devuelve como excepción".
int isLegal (int dt) lanza LowZeroException //Esta definición se denomina método con una "excepción" en este artículo
{ //Los lanzamientos establecen una asociación
if (dt>=0){
devolver datos;
}
devolver datos
devolver datos. p>
}
else
throw new LowZeroException();
}
/* auto- clase Exception escrita, heredada de Exception*
class LowZeroException extends Exception
{
public LowZeroException(){
super();
}
}
Si observamos de cerca el método isLegal(), la característica más notable que incorpora es que sale de la función de dos maneras. Una es devolver una instancia del tipo definido por el método en sí a través de la declaración de retorno; la otra es devolver una instancia del objeto "clase de excepción" a través de la declaración de lanzamiento, que en Java se denomina lanzar una "excepción". Compare esto con cómo se maneja el mismo problema en C:
int isLegal(int dt) {
if (dt>=0){
return data ;
}
else
return -1; //Valor específico que indica un error<
}
Dado que el lenguaje C solo puede devolver valores de función mediante retorno, las excepciones se pueden manejar de la manera anterior. Por supuesto, esto requiere que los usuarios de la función isLegal() tengan cuidado al utilizar un valor de retorno -1 en la función para indicar la presencia de datos ilegales.
Al comparar estos dos métodos, podemos ver claramente que el "mecanismo de excepción" de Java separa la función de manejar excepciones de la función del método en sí a través de dos salidas diferentes.
Todas estas "clases de excepción" están organizadas en un único árbol de clases, independientemente de los métodos a los que sirven específicamente. Este "mecanismo anormal" es similar a la socialización de la logística universitaria, es decir, las funciones docentes de la escuela están separadas del apoyo logístico de la escuela y la organización del grupo logístico es independiente del cuerpo principal de la escuela. La práctica ha demostrado que esta forma organizativa no sólo mejora la eficiencia del servicio, sino que también mejora la calidad del servicio. La organización de las "Clases de excepción" en todo el sistema Java se muestra en la Figura 1:
Si el método isLegal() en el Ejemplo 1 no devuelve un número normal durante el proceso de llamada, sino en la "Clases de excepción" "Se genera un objeto de "excepción" en el punto de generación, entonces, ¿quién recibirá y manejará este objeto de "excepción"? Respondamos esta pregunta a continuación.
2. Proceso de procesamiento de "excepciones"
Java maneja "excepciones" mediante la sintaxis try...catch e incluye los métodos asociados con la "clase de excepción" en el bloque try{ } , la palabra clave catch () {} se puede utilizar en forma de parámetro junto con un método que genera un objeto de "excepción". Cuando se llama a un método y se cumplen las condiciones que causan que ocurra una excepción, se generará la "excepción", el flujo del programa original se interrumpirá en este método y luego el módulo de prueba cambiará los "parámetros formales" en el catch "Complete la combinación con el objeto de excepción y luego ingrese al módulo catch para ejecutarlo.
Ejemplo de este proceso:
Ejemplo 2:
/* Incluir el método asociado con la excepción en el módulo try*
int myMethod(int dt){
int datos = 0;
intentar{
int datos = isLegal(dt);
}catch ( LowZeroException e){
System.out.println("¡Se ha producido un error de datos!")
}
devuelve datos;
}
Tercero, manejar la "excepción"
Hay dos formas de manejar la "excepción": la primera es como se muestra en el Ejemplo 2, el método que contendrá la "excepción" Exportado directamente en el bloque try y luego capturado por el siguiente bloque catch. El segundo método no es monitorear y capturar directamente la "excepción" del método de referencia, sino pasar la asociación de "excepción" al método de referencia y, al mismo tiempo, el trabajo de monitoreo y captura también se pasa en consecuencia.
Ejemplo 3:
int myMethod2(int dt)
{
int data = 0;
try{
data = myMethod(dt)
}catch(LowZeroException e){
System.out.println("Un error de datos ocurrió!") ;
e.printStackTrace();
}
Devolver datos;
}
int myMethod(int dt) throws LowZeroException
{
int data = isLegal(dt); // Aquí se hace referencia al método isLegal(), pero no a su "excepción". Capturar
Devolver datos
}
En el ejemplo anterior, puede ver que el método myMethod() y su método referenciado isLegal() producen una "Excepción". " creó una excepción LowZeroException. LowZeroException, es decir, se completa la transmisión ascendente relacionada con la "excepción". Aunque el cuerpo del método myMethod () en este momento solo tiene una declaración de devolución, en realidad también tiene dos métodos de exportación de funciones. un valor. El otro es devolver la palabra clave throws en el nombre del método, y el otro es devolver una instancia de la "clase de excepción" a la que se hace referencia en el nombre del método. Por lo tanto, la tarea de escuchar y capturar se asigna al método superior myMethod2(). Del mismo modo, myMethod2() puede pasar "excepciones" a través de la asociación de lanzamientos. De esta manera, una vez capturada la "Excepción", la "Excepción" debe tener una ruta de entrega. Si agregamos el método printStackTrace() en el bloque catch del punto de captura, podemos ver claramente cómo se entrega la "Excepción". .
Por ejemplo, en el Ejemplo 3, si se detecta una "Excepción", e.printStackTrace() imprimirá:
LowZeroException:
en Ejemplo.isLegal
en Ejemplo myMethod
en Ejemplo.myMethod2
en Ejemplo principal
Como se puede ver en los resultados anteriores, comenzamos desde el punto donde LowZeroException "Excepción" se genera, es decir, el método que contiene la cláusula throw new LowZeroException(), y luego se rastrea hasta el método que generó el hilo actual (nota: el método que generó la LowZeroException() actual). El método que generó el hilo actual (nota: printStackTrace() no se remonta hasta el final del punto de captura, sino hasta el final del método que generó los objetos de "Excepción" LowZeroException generados en la "Excepción"). primero se asignan los puntos de generación. Proporcione una referencia sin nombre a la clase LowZeroException asociada con isLegal(), luego proceda a asignar una referencia sin nombre a la clase LowZeroException asociada con myMethod(), luego proceda a asignar una referencia sin nombre a la clase LowZeroException en el archivo catch. bloque en myMethod2() , luego vaya al parámetro formal e en el bloque de código catch en myMethod2() y finalmente procéselo aquí, y el objeto "excepción" desaparece. Se puede decir que catch(){} es. el final de la vida útil del objeto "excepción"
Tenga en cuenta también que los métodos asociados con la "excepción" siempre se pueden pasar hacia arriba cuando se pasa al método principal () asociado con el método principal. usando la definición de excepción throws, además de la máquina virtual, no hay otra forma de hacer referencia al método main (), y es posible que el bloque try.............catch no sea visible en el programa, pero no generará un error porque En este momento, la máquina virtual capturará la "excepción" y llamará al método printStackTrace () de forma predeterminada para imprimir la ruta de la "excepción". El método está asociado con una "excepción", puede pasar la asociación de "excepción", pero eventualmente deberá usar catch para terminar esta "excepción", o hasta que se use el método main () para finalizar la vida útil de la máquina virtual Java para este objeto de "excepción", de lo contrario no se compilará
4. Utilice varios puntos a tener en cuenta sobre el "mecanismo de excepción"
1. Un método puede generar múltiples excepciones diferentes. y se pueden establecer múltiples puntos de lanzamiento de "excepción" para resolver este problema.
2. Todo el proceso, desde generar el objeto de excepción hasta capturar y finalizar el objeto de excepción, es en realidad un proceso de entrega, por lo que puede controlarlo. la granularidad de la excepción detectada según sea necesario. Por ejemplo, en el Ejemplo 3, si no necesita conocer la "Excepción LowZeroException" específica, puede usar la "Excepción" de la excepción principal del dios público para combinar. el objeto "Excepción", es decir, catch (Exception e) {...} De manera similar, al pasar la "Excepción" a la asociación del método, puede controlar la granularidad de la "excepción" asociada según sea necesario, es decir, agregar el nombre de la clase principal del objeto de excepción después de los lanzamientos.
3. También existe un caso especial de RuntimeException "Clase de excepción" en el "Mecanismo de excepción". La "clase de excepción" y todas sus subclases tienen la característica de que una vez generado el objeto "excepción", será procesado directamente por la máquina virtual Java, es decir, siempre que el método contenga una cláusula de lanzamiento, el método. Será capturado por la máquina virtual.
Por lo tanto, cualquier método que genere una "excepción de tiempo de ejecución" no necesita usar una declaración try...catch para manejar la "excepción" cuando se llama.