Prefacio
En el proceso de aprendizaje de Java, creo que todos han aprendido el capítulo sobre excepciones, y no hablaré sobre las características básicas y el uso de excepciones aquí. ¿Qué es una excepción? No sé cómo todos lo entienden. Mi comprensión es muy simple, es decir, situaciones anormales. Por ejemplo, ahora soy un hombre, pero tengo algo único para las mujeres. En mi opinión, esto es definitivamente una anormalidad y no puedo soportarlo. Creo que todos pueden entenderlo y usarlo correctamente.
Sin embargo, si el procesamiento y el uso de excepciones básicas ópticas es insuficiente, no da miedo ocurrir en el trabajo. A veces es necesario usar excepciones para impulsar el procesamiento del negocio. Por ejemplo: cuando se usa una base de datos con restricciones únicas, si se inserta un duplicado datos, se puede procesar capturando la excepción de restricción única DuplicateKeyException. En este momento, el estado correspondiente se puede lanzar a la capa de llamada en la capa del servidor, y la capa superior lo procesará de acuerdo con el estado correspondiente. Por lo tanto, a veces las excepciones son un método de conducción para el negocio.
Algunas personas generarán la excepción después de detectar la excepción. Me pregunto si los estudiantes cuidadosos han notado algo. ¿Cuál es la excepción de salida?
Aquí hay una excepción común:
java.lang.arithmeticException: / by cero en greenhouse.exceptionTest.testexception (excepcionTest.java:16) en Sun.reflect.nativemethodaccessorImpl.invoke0 (método nativo) en Sun.reflect.nativeMethodaccessImpl.invoke (NativemethodaccessessImpl.JaSppl.JaV.JaT Sun.Reflect.DelegatingMethodacCessorImpl.invoke (delegación deMethodAccessorImpl.java:25) en java.lang.reflect.method.invoke (método.java:597) en org.junit.runners.model.frameworkmethod $ 1.RunreflectivEcall (marmano) en org.junit.internal.runners.model.reflectiveCallable org.junit.internal.runners.statements.invokemethod.evaluate (invokemethod.java:20) en org.junit.runners.blockjunit4classrunner.runchild (blockjunit4classrunner.java:76) en org.junit.runners.blockjunit4classrunner.runchild (blockjunit4classrunner.java:50) en org.junit.runners.parentrunner $ 3.run (parentrunner.java:193) en org.junit.runners.parentrunner $ 1.schedule org.junit.runners.parentrunner.runchildren (parentrunner.java:191) en org.junit.runners.parentrunner.access $ 000 (parentrunner.java:42) en org.junit.runners.parentrunner $ 2.evaluate (parentrunner.java:184) organización com.intellij.rt.execution.junit.ideAteatestrunner $ reembolsado com.intellij.rt.execution.junit.junitstarter.main (Junitstarter.java:70)
Una excepción de puntero nulo:
java.lang.nullpointerexception en greenhouse.exceptionTest.testexception (excepcionTest.java:16) en Sun.reflect.nativemethodaccessorImpl.invoke0 (método nativo) en Sun.reflect.nativemethodaccessorMpl.invoke (nativemethodaccessimpl.Java:39) Sun.Reflect.DelegatingMethodacCessorImpl.invoke (delegación deMethodAccessorImpl.java:25) en java.lang.reflect.method.invoke (método.java:597) en org.junit.runners.model.frameworkmethod $ 1.RunreflectivEcall (marmano) en org.junit.internal.runners.model.reflectiveCallable org.junit.internal.runners.statements.invokemethod.evaluate (invokemethod.java:20) en org.junit.runners.blockjunit4classrunner.runchild (blockjunit4classrunner.java:76) en org.junit.runners.blockjunit4classrunner.runchild (blockjunit4classrunner.java:50) en org.junit.runners.parentrunner $ 3.run (parentrunner.java:193) en org.junit.runners.parentrunner $ 1.schedule org.junit.runners.parentrunner.runchildren (parentrunner.java:191) en org.junit.runners.parentrunner.access $ 000 (parentrunner.java:42) en org.junit.runners.parentrunner $ 2.evaluate (parentrunner.java:184) organización com.intellij.rt.execution.junit.ideAteatestrunner $ reembolsado com.intellij.rt.execution.junit.junitstarter.main (Junitstarter.java:70)
¿Ha encontrado una característica de que la salida de la excepción es la ubicación donde se produce la excepción con precisión, y muchas llamadas de proceso de ejecución se imprimen más adelante. ¿De dónde viene esta información? Esta información se obtiene de la pila. Al imprimir el registro de excepciones, esta información de la llamada se obtendrá de la pila. Por supuesto, es bueno poder ubicar con precisión las excepciones, pero a veces, cuando consideramos el rendimiento del programa y algunos requisitos, a veces no necesitamos imprimir esta información por completo y obtener la información correspondiente de la pila de llamadas del método, que es el consumo de rendimiento. Para algunos programas con requisitos de alto rendimiento, podemos mejorar por completo el rendimiento del programa en este aspecto.
Entonces, ¿cómo evitar producir esta información de pila? Entonces las excepciones personalizadas pueden resolver este problema:
Primero, la excepción automática debe heredar el RuntimeException y luego reescribir el método FillinStackTrace y ToString. Por ejemplo, defino una excepción de AppException a continuación:
paquete com.green.monitor.common.exception; import java.text.messageformat;/*** Class de excepción personalizada*/public class AppException extiende RuntimeException {private boolean issuccess = false; clave de cadena privada; Información de cadena privada; public appException (tecla de cadena) {super (clave); this.key = key; this.info = key; } public appException (clave de cadena, mensaje de cadena) {super (MessageFormat.Format ("{0} [{1}]", clave, mensaje)); this.key = key; this.info = mensaje; } public appException (mensaje de cadena, tecla de cadena, info de cadena) {super (mensaje); this.key = key; this.info = info; } public boolean issuccess () {return issuccess; } public String getKey () {Key de retorno; } public void setKey (tecla de cadena) {this.key = key; } public String getInfo () {Información de retorno; } public void setInfo (info de cadena) {this.info = info; } @Override public showleable FillInStackTrace () {return this; } @Override public string toString () {return MessageFormat.Format ("{0} [{1}]", this.key, this.info); }}Entonces, ¿por qué reescribir FillinStackTrace y los métodos de tostración? Veamos primero cuál es el código fuente.
Public Class RuntimeException extiende la excepción {estática final de serie Long -LongUid = -7034897190745766939l; /** Construye una nueva excepción de tiempo de ejecución con <code> null </code> como su* mensaje de detalle. La causa no se inicializa, y posteriormente puede * inicializarse mediante una llamada a {@link #InitCause}. */ public runtimeException () {super (); } /** Construye una nueva excepción de tiempo de ejecución con el mensaje de detalle especificado. * La causa no se inicializa y puede inicializarse mediante una llamada * a {@link #InitCause}. * * @param Mensaje El mensaje de detalle. El mensaje detallado se guarda para * recuperación posterior mediante el método {@link #getMessage ()}. */ public runtimeException (mensaje de cadena) {super (mensaje); } /** * Construye una nueva excepción de tiempo de ejecución con el mensaje de detalle especificado y * causa. <p> Tenga en cuenta que el mensaje detallado asociado con * <code> causa </code> es <i> no </i> incorporado automáticamente en * el mensaje de detalle de esta excepción de tiempo de ejecución. * * @param Mensaje El mensaje de detalle (que se guarda para la recuperación posterior * por el método {@link #getMessage ()}). * @param causa la causa (que se guarda para la recuperación posterior por el método * {@link #getCause ()}). (A <tt> nulo </tt> valor está * permitido, e indica que la causa es inexistente o * desconocida.) * @Since 1.4 */ public runtimeException (mensaje de cadena, causa tirada) {super (mensaje, causa); }/** Constructs una nueva excepción de tiempo de ejecución con la causa especificada y un * mensaje detallado de <TT> (Cause == NULL? NULL: Cause.ToString ()) </tt> * (que típicamente contiene el mensaje de clase y detalle de * <tt> causa </tt>). Este constructor es útil para las excepciones de tiempo de ejecución * que son poco más que envoltorios para otros lanzamientos. * * @param causa la causa (que se guarda para la recuperación posterior por el método * {@link #getCause ()}). (A <tt> nulo </tt> valor está * permitido e indica que la causa es inexistente o * desconocida.) * @Since 1.4 */ public runtimeException (causa de lanzamiento) {super (causa); }}RuntimeException hereda la excepción, pero solo llama al método de la clase principal y no hace ninguna otra operación. Entonces, ¿sigamos viendo qué está pasando en excepción?
La excepción de la clase pública extiende lanzable {static final Long SerialVersionUid = -33875169931242299948l; /*** Construye una nueva excepción con <code> null </code> como mensaje de detalle. * La causa no se inicializa, y se puede inicializar posteriormente mediante un * llamado a {@link #InitCause}. */ Public Exception () {super (); } /*** Construye una nueva excepción con el mensaje de detalle especificado. La causa * no se inicializa, y posteriormente se puede inicializar * una llamada a {@link #InitCause}. * * @param Mensaje El mensaje de detalle. El mensaje detallado se guarda para * recuperación posterior mediante el método {@link #getMessage ()}. */ Public Exception (Mensaje de cadena) {Super (Mensaje); } /** * Construye una nueva excepción con el mensaje de detalle especificado y * causa. <p> Tenga en cuenta que el mensaje detallado asociado con * <code> causa </code> <i> no se incorpora automáticamente en * el mensaje de detalle de esta excepción. * * @param Mensaje El mensaje de detalle (que se guarda para la recuperación posterior * por el método {@link #getMessage ()}). * @param causa la causa (que se guarda para la recuperación posterior por el método * {@link #getCause ()}). (A <tt> nulo </tt> valor está * permitido e indica que la causa es inexistente o * desconocida.) * @Since 1.4 */ excepción pública (mensaje de cadena, causa de lanzamiento) {super (mensaje, causa); }/** * Construye una nueva excepción con la causa especificada y un detalle * Mensaje de <Tt> (Cause == NULL? NULL: Cause.ToString ()) </tt> (que * típicamente contiene el mensaje de clase y detalle de <tt> causa </tt>). * Este constructor es útil para excepciones que son poco más que * envoltorios para otros lanzamientos (por ejemplo, {@link * java.security.privilegedActionException}). * * @param causa la causa (que se guarda para la recuperación posterior por el método * {@link #getCause ()}). (A <tt> nulo </tt> valor está * permitido e indica que la causa es inexistente o * desconocida.) * @Since 1.4 */ excepción pública (causa tirada) {super (causa); }}Como se puede ver en el código fuente, el método de clase principal también se llama directamente en excepción. Como RuntimeException, en realidad no hice nada. Así que echemos un vistazo a lo que está pasando en lanzamiento:
Public Class Showable Implements Serializable {public Throwable (String Message) {FillInStackTrace (); DetellMessage = Mensaje; } /*** Completa el rastro de la pila de ejecución. Este método registra esta información de objeto * <code> throwable </code> sobre el estado actual de * los marcos de pila para el hilo actual. * * @return una referencia a esta instancia <code> lanzable </code>. * @see java.lang.throwable#printStackTrace () */ public synchronized Native Throwable FillInStackTrace (); /** * Proporciona acceso de programación a la información de rastreo de pila impreso por * {@link #PrintStackTrace ()}. Devuelve una matriz de elementos de rastreo de pila, * cada uno representando un marco de pila. El elemento cero de la matriz * (suponiendo que la longitud de la matriz no sea cero) representa la parte superior de la pila *, que es la última invocación del método en la secuencia. Típicamente, * este es el punto en el que se creó y lanzó este lanzamiento. * El último elemento de la matriz (suponiendo que la longitud de la matriz no sea cero) * representa la parte inferior de la pila, que es la primera invocación del método * en la secuencia. * * <p> Algunas máquinas virtuales pueden, en algunas circunstancias, omitir uno * o más marcos de pila del rastro de la pila. En el caso extremo, * una máquina virtual que no tiene información de rastreo de pila con respecto * Este lanzamiento puede devolver una matriz de longitud cero de este método *. En términos generales, la matriz devuelta por este método * contendrá un elemento para cada cuadro que se imprima por * <tt> printStackTrace </tt>. * * @return una matriz de elementos de rastreo de pila que representan el rastro de la pila * perteneciente a este lanzamiento. * @since 1.4 */ public stackTraceElement [] getStackTrace () {return (stackTraceElement []) getourStackTrace (). clone (); } stackTraceElement sincronizado privado [] getourStackTrace () {// Inicializar Trace de pila Si esta es la primera llamada a este método if (stackTrace == null) {int profundidad = getStackTraCedEpth (); stackTrace = new StackTraceElement [profundidad]; para (int i = 0; i <profundidad; i ++) stacktrace [i] = getStackTraceElement (i); } return StackTrace; } /** * Devuelve el número de elementos en el rastro de la pila (o 0 si el rastro de pila * no está disponible). * * PROTECCIÓN DE PAGACE para usar por SharedSecrets. */ national int getStackTraCedEpth (); /*** Devuelve el elemento especificado del rastro de pila. * * PROTECCIÓN DE PAGACE para usar por SharedSecrets. * * @Param Índice del elemento para devolver. * @throws indexOutofBoundsexception si <TT> índice <0 || * index> = getStackTraCePth () </tt> */ national stackTraceElement getStackTRaceElement (int index); /*** Devuelve una breve descripción de este lanzamiento. * El resultado es la concatenación de: * <ul> * <li> el {@linklain class #getName () name} de la clase de este objeto * <li> ":" (un colon y un espacio) * <li> El resultado de invocar este objeto {@link #getLocalizedMessage} * método * </lul> * if <ttlocalmess </tt tt devuelve <tt> null </tt>, luego solo * se devuelve el nombre de la clase. * * @return una representación de cadena de este lanzamiento. */ public string toString () {String s = getClass (). getName (); String Message = getLocalizedMessage (); return (mensaje! = nulo)? (S + ":" + Mensaje): S; }Del código fuente, está casi por el final del lanzamiento. El método FillinStackTrace () es un método nativo. Este método llamará al lenguaje C subyacente, devolverá un objeto lanzable, el método de tostración y devuelve una breve descripción del lanzamiento. En el método GetStackTrace y GetourStackTrace, se llama al método nativo GetStackTRaceElement. Este método devuelve la información del elemento de pila especificada, por lo que este proceso debe consumir rendimiento. Luego podemos reescribir el método ToString y el método FillInStackTrace en excepciones personalizadas y obtenerlo directamente sin obtener información de excepción de la pila. Esto no es relativamente "pesado" para el sistema y el programa, y es una muy buena manera de optimizar el rendimiento. Entonces, ¿cómo se ve si se produce una excepción personalizada? Consulte a continuación:
@Test public void testException () {try {string str = null; System.out.println (str.charat (0)); } Catch (Exception e) {tire nueva appException ("000001", "excepción de puntero nulo"); }}Luego, cuando la excepción es anormal, el sistema imprimirá nuestra información de excepción personalizada:
000001 [Excepción del puntero nulo] Proceso terminado con el código de salida -1
Por lo tanto, es particularmente conciso y optimiza el rendimiento del programa del sistema, lo que hace que el programa sea menos "pesado", por lo que se requiere el sistema con requisitos de rendimiento especiales. ¡Date prisa y personaliza tu propia excepción!
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.