La palabra anormal en inglés es una excepción, y la traducción literal significa "accidente, excepción", lo que significa situaciones anormales. De hecho, las excepciones son esencialmente errores del programa, incluidos los errores lógicos del programa y los errores del sistema.
Un prefacio
Todos están familiarizados con el manejo de excepciones de Java, en general, hay dos puntos:
1. Excepción de lanzamiento: Excepción de lanzamiento
clase SimpleException {public void a () lanza excepción {throw new Exception (); };}2. Excepciones de captura:
clase pública myException {public static void main (string [] args) {myException e = new myException (); SimpleException SE = new SimpleException (); intente {se.a (); } catch (excepción e1) {e1.printstackTrace (); }}} class SimpleException {public void a () lanza excepción {lanzar una nueva excepción (); };}Este artículo discutirá algunos detalles sobre esta base más profunda.
Dos clase de excepción personalizada
El idioma Java nos proporciona muchas clases de excepción, pero a veces todavía tenemos que personalizar las clases de excepción para la conveniencia de escribir código:
La clase SimpleException extiende la excepción {};
Después de la creación, podemos usar TRAT Catch para capturarlo:
clase pública myException {public static void main (string [] args) {myException e = new myException (); prueba {ea (); } catch (SimpleException e1) {e1.printStackTrace (); }} public void a () lanza SimpleException {Throw New SimpleException (); }} clase SimpleException extiende la excepción {};Definimos un método A () en MyException, dejamos que lanzar una excepción de SimpleException, luego llamamos a este método en Main () y atrapamos esta excepción usando la captura de prueba:
SimpleException en myException.a (myException.java:15) en myException.main (myException.java:8) en Sun.reflect.nativemethodaccessorImpl.invoke0 (método nativo) en Sun.reflect.nativemethodaccessorMpl.invoke (nativemethodaccessimpl.Java:57) Sun.reflect.DelegatingMethodacCessorImpl.invoke (delegatingmethodacCessorImpl.java:43) en java.lang.reflect.method.invoke (método.java:606) en com.intellij.rt.execution.application.appmain.main (appmain.Java:14) en com.intelliJ.rt.execution.application.appmain.main (appmain.Java:14) en com.rt.rt.execution.application.appmain.main (appmain.Java:14) en com.intelliJ.rt.execution.application.appmain.main (appmain.Java:14)
El resultado después de la compilación y la ejecución se basa principalmente en las tres primeras líneas. Aquí hay algunos puntos a explicar:
1. Especifique el tipo de excepción: (especificación de excepción)
Cuando necesitamos lanzar una excepción en un método, usamos lanzar y agregar una instancia de una clase de excepción. El programa lanzará la excepción correspondiente al programa del cliente (el programa que llama a este código) y saldrá aquí (equivalente a la devolución). También tenga en cuenta que debemos especificar el tipo de excepción al definir este método. Por ejemplo, el siguiente código lanzará una excepción de Excepción Simple
el vacío público a () lanza SimpleException
2. Lanza múltiples excepciones:
public void a () lanza SimpleException, AException, Bexception {Throw New SimpleException (); }Las diferentes clases de excepción pueden separarse por comas. En este caso, no tenemos que lanzar cada instancia de clase de excepción (), pero el código del cliente debe captar cada clase de excepción:
clase pública myException {public static void main (string [] args) {myException e = new myException (); prueba {ea (); } catch (SimpleException e1) {e1.printStackTrace (); } catch (bexception e1) {e1.printstacktrace (); } catch (aException e1) {e1.printstackTrace (); }} public void a () lanza SimpleException, AException, Bexception {Throw New SimpleException (); }} class SimpleException extiende la excepción {}; la clase AException extiende la excepción {} La clase Bexception extiende la excepción {} Tres traza de pila
Ya sea que se trate de excepciones o excepciones de captura y manejo, nuestro propósito es escribir un programa más robusto, que depende en gran medida de la información de excepción proporcionada por el mecanismo de excepción de Java, y su portador es traza de pila.
En el código anterior, usamos directamente PrintStackTrace () para imprimir información de excepción. De hecho, también podemos usar el método GetStackTrace () para obtener una colección de StackTraceElement. Si tiene una idea a mano, primero puede buscar la clase StackTraceElement, y puede encontrar que implementa la interfaz serializable y luego echar un vistazo a su descripción de clase:
/** * Un elemento en un rastro de pila, según lo devuelto por {@link * showable#getStackTrace ()}. Cada elemento representa un solo marco de pila. * Todos los marcos de pila, excepto el que está en la parte superior de la pila, representan * una invocación de método. El marco en la parte superior de la pila representa el punto de ejecución * en el que se generó el rastro de la pila. Típicamente, * este es el punto en el que se creó el lanzamiento correspondiente al trazo de la pila *. * * @since 1.4 * @author Josh Bloch */Está claro que cada instancia de esta clase es un elemento de la traza de la pila, que representa un marco de pila, y el método GetStackTrace () devuelve el rastro de la pila. Traté de traducir lo siguiente varias veces, pero sentí que no era bueno, por lo que podría escribir el código directamente para explicarlo:
clase pública myException {public static void main (string [] args) {myException e = new myException (); ea (); public void a () {try {lanzar nueva excepción (); } catch (excepción e) {stackTraceElement [] ste = e.getStackTrace (); System.out.println (ste.length); }}}Definimos el Método A, dejamos que organice una excepción de excepción mientras la capturamos, y luego obtenemos una matriz StackTraceElement a través del método getStackTrace () e imprime la longitud de la matriz:
7
Proceso terminado con el código de salida 0
Cambiamos un poco el código y dejamos de captar excepciones en a. Redefinimos un método B para que capte excepciones mientras llamamos a:
clase pública myException {public static void main (string [] args) {myException e = new myException (); eb (); } public void b () {try {a (); } catch (excepción e) {stackTraceElement [] ste = e.getStackTrace (); System.out.println (ste.length); }} public void a () lanza excepción {tirar nueva excepción (); }}Los resultados son los siguientes:
8
Proceso terminado con el código de salida 0
No te preocupes, echemos un vistazo a algo interesante:
clase pública myException {public static void main (string [] args) {myException excepción = new myException (); intente {excepcion.c (); } catch (excepción e) {stackTraceElement [] ste = e.getStackTrace (); System.out.println (ste.length); System.out.println ("---------------------------------------------------------------"); for (stackTraceElement s: e.getStackTrace ()) {system.out.println (s.getClassName ()+": método"+s.getMethodName ()+"at línea"+s.getLinEnumber ()); } System.out.println ("---------------------------------------------------------------"); }} public void c () lanza excepción {try {a (); } Catch (Exception e) {Throw E; }} public void a () lanza excepción {tirar nueva excepción (); }}Aquí están los resultados:
8 --------------------------------------------------- line57sun.reflect.delegatingMethodacCessorImpl: Method Invoke en Line43java.lang.reflect.method: método Invocar en Line606com.intellij.rt.execution.Application.AppMain: Método principal en Line144 ------------------------------------------------------- proceso terminado con el proceso de exit.
Es decir, getStackTrace () devuelve una pila, que contiene información básica de la persona que llama (main ()) a la excepción de lanzamiento inicial (a ()). En el código anterior, captamos la excepción al llamar al método A en el método C y volver a lanzarlo a través de lanzamientos. El método que llama al método C puede atrapar y manejar la excepción, o puede elegir continuar lanzando para permitir que las personas que llaman de nivel superior (cerca de la parte inferior de la pila) lo manejen. Aunque Rethrow es muy conveniente, hay algunos problemas. Veamos el siguiente código:
clase pública myException {public static void main (string [] args) {myException excepción = new myException (); intente {excepcion.c (); } catch (Exception e) {E.PrintStackTrace (System.out); }} public void c () lanza excepción {try {a (); } Catch (Exception e) {Throw E; }} public void a () lanza la excepción {tirar nueva excepción ("excepción de a ()"); }} java.lang.exception: excepción de a () en myException.a (myException.java:40) en myException.c (myException.java:30) en myException.main (myException.java:21)Revuelve E en C e imprimimos con E.PrintStackTrace () en Main. Puede ver que la traza de la pila impresa todavía pertenece a a. Si queremos convertir el rastro de la pila en C, podemos escribirlo así:
clase pública myException {public static void main (string [] args) {myException excepción = new myException (); intente {excepcion.c (); } catch (Exception e) {E.PrintStackTrace (System.out); }} public void c () lanza excepción {try {a (); } Catch (Exception e) {// tirar e; lanzar (excepción) E.FillinStackTrace (); }} public void a () lanza la excepción {tirar nueva excepción ("excepción de a ()"); }} java.lang.Exception: Excepción de a () en myException.c (myException.java:22) en myException.main (myException.java:10) Cuatro excepciones de excepción
Echemos un vistazo a un escenario:
public class testException {public static void main (string [] args) {testException testException = new testException (); intente {testException.c (); } catch (CException e) {E.PrintStackTrace (); }} public void a () lanza aException {aException aException = new aException ("Esta es una excepción"); tirar aexception; } public void b () lanza Bexception {try {a (); } catch (aException e) {tirar nueva bexception ("esta es b excepción"); }} public void c () arroja cexception {try {b (); } catch (bexception e) {tire nueva cexception ("Esta es una excepción"); }}} La clase AException extiende la excepción {public aException (String msg) {super (msg); }} La clase Bexception extiende la excepción {public Bexception (String Msg) {super (msg); }} class CException extiende la excepción {public cException (String msg) {super (msg); }}Se crean tres clases de excepción aException, Bexception y Cexception, luego se lanza aException en A (), AException se atrapa en B () y Bexception se arroja, y finalmente Bexception se atrapa en c () y se lanza Cexception, y el resultado se imprime de la siguiente manera:
Cexception: esta es una excepción C en testException.c (testException.java:31) en testException.main (testException.java:8)
Ok, solo vemos la información de Cexception, AException y Bexception se han perdido, y saldrá la función de la cadena de excepciones, vea el código:
public class testException {public static void main (string [] args) {testException testException = new testException (); intente {testException.c (); } catch (CException e) {E.PrintStackTrace (); }} public void a () lanza aException {aException aException = new aException ("Esta es una excepción"); tirar aexception; } public void b () lanza Bexception {try {a (); } catch (aException e) {// tirar nueva bexception ("esta es b excepción"); Bexception bexception = new Bexception ("Esta es la excepción B"); bexception.initCause (e); tirar bexception; }} public void c () arroja cexception {try {b (); } catch (bexception e) {// tirar nueva cexception ("Esta es una excepción"); Cexception cException = new CException ("Esta es una excepción c"); cException.initCause (e); tirar cexception; }}} La clase AException extiende la excepción {public aException (String msg) {super (msg); }} La clase Bexception extiende la excepción {public Bexception (String Msg) {super (msg); }} class CException extiende la excepción {public cException (String msg) {super (msg); }}Utilizamos el método initCause () para conectar la información de excepción, y el resultado es el siguiente:
Cexception: Esta es una excepción C en testException.c (testException.java:35) en testException.main (testException.java:8) en sun.reflect.nativemethodaccessorImpl.invoke0 (método nativo) en sun.reflect.nativemethodaccesspl.invoke (nativemethodaccsessimpl.JaT.57) Sun.reflect.DelegatingMethodacCessorImpl.invoke (delegatingmethodacCessorImpl.java:43) en java.lang.reflect.method.invoke (método.java:606) en com.intellij.rt.execution.application.appmain.main (appmain.Java:14) en com.rt.execution.application.appmain.main (appmain.Java:14) por: es b excepción en testException.b (testException.java:24) en testException.c (testException.java:32) ... 6 Morecaused por: aException: esta es una excepción en testException.a (testException.java:15) en testException.b (testException.Java:21) ... 7 MoreProcess terminó con exit Code 0 0 Code 0 exit Code 0
El PostScript de los cinco
De hecho, todavía hay muchas cosas que discutir sobre el manejo de excepciones de Java, pero debido a que tengo una experiencia limitada, no puedo entenderlo demasiado profundamente, y el más utilizado es
Pruebe {...} Catch (Exception e) {...} Finalmente {// código que se ejecutará independientemente de si la excepción será atrapada o procesada, como cerrar operaciones IO}Pero pase lo que pase, todavía tenemos que agradecer a Java por proporcionarnos el mecanismo de excepción. Es como un anciano, que nos guía de vez en cuando y nos hace menos aburridos al codificar :)