JavaRush /Blog Java /Random-ES /Stack Trace y con qué se come
Alukard
Nivel 37
London

Stack Trace y con qué se come

Publicado en el grupo Random-ES
En este artículo, aprenderá y comprenderá cómo funciona el fenómeno Java StackTrace, también conocido como Call Stack Tracing. Esta información ha sido estructurada para principiantes que encontraron este concepto al comienzo del nivel 9 de sintaxis de Java. Creo que todos ustedes, al menos una vez, se han encontrado con errores similares al trabajar en su IDE, sin importar si era Idea , Eclipse u otra cosa.
Exception in thread "main" java.lang.ArithmeticException
	at com.example.task01.Test.division(Test.java:10)
	at com.example.task01.Test.main(Test.java:6)
Este, como habrás adivinado, es nuestro rastreo. Pero no se apresure a entrar en pánico, ahora le desglosaremos este ejemplo. Primero debes entender el hecho de que StackTracefunciona como Стэкsu nombre indica. En este punto nos detendremos un poco más en detalle. Cómo funciona la colección Stack En el octavo nivel, ya se ha familiarizado con las colecciones y sabe que están divididas en tres grupos Set: conjunto, Listlista, Mapdiccionario (o mapa). Según JavaRush (c). El nuestro Stackes parte del grupo List. El principio de funcionamiento se puede describir como LIFO , que significa Last In First Out. Es decir, esta es una lista similar a una pila de libros; para tomar el elemento que colocamos Stackprimero, primero debemos extraer todos los elementos que agregamos a nuestra lista después. Como se indica en la imagen de arriba, a diferencia de, por ejemplo, una lista normal ArrayListdonde podemos obtener cualquier elemento de la lista por índice. Una vez más para reforzar. ¡Obtener un elemento Стэкаsolo es posible desde el final! Mientras que el primer elemento que se le agrega está al principio (o en la parte inferior, como sea más conveniente). Estos son los métodos que tiene nuestro Stack Objeto push(): Agrega un elemento a la parte superior de la pila. Objeto pop(): devuelve el elemento en la parte superior de la pila y lo elimina en el proceso. Objeto peek(): devuelve el elemento en la parte superior de la pila, pero no lo elimina. int search(): busca un elemento en la pila. Si se encuentra, se devuelve su desplazamiento desde la parte superior de la pila. De lo contrario, se devuelve -1. booleano empty(): comprueba si la pila está vacía. Devuelve verdadero si la pila está vacía. Devuelve falso si la pila contiene elementos. Entonces, ¿por qué necesita Javauno StackTracebasado en los principios de funcionamiento Stack? Veamos el siguiente ejemplo de un error que ocurrió durante la ejecución de un programa tan simple.
public class Test {

    public static void main(String[] args) {
        System.out.println(convertStringToInt(null));
    }

    public static int convertStringToInt(String s) {
        int x = Integer.parseInt(s);
        return x;
    }
}
Tenemos una clase Testcon dos métodos. Todo el mundo lo sabe mainy convertStringToIntcuya lógica es convertir y devolver una cadena recibida desde el exterior (es decir, del método main) en un número entero de tipo int. Como puede ver, pasamos intencionalmente el parámetro en lugar de una cadena con algún número null. Nuestro método no pudo procesar este parámetro correctamente y provocó un error NumberFormatException. Como saben el programa comienza a realizar su trabajo a partir del método mainy en este momento crea uno nuevo Стэкcon un nombre StackTracedonde pone el valor actual de su trabajo bajo el número 1 , luego vamos al método convertStringToInty al programa nuevamente. ingresa los parámetros de nuestra ubicación en el creado anteriormente StackTracebajo el número 2 , luego se llama un método invisible a nuestros ojos parseIntubicado en la clase Integery este ya será el elemento número 3 nuestro StackTrace, en este método se agregará otra llamada interna al StackTracenúmero 4 para comprobar si el elemento es nulo , lo que provocará un error. El programa necesita mostrar nuestro error indicando la cadena completa de nuestras transiciones hasta que ocurrió el error. Aquí es donde viene en su ayuda el creado previamente con los datos de nuestras transiciones StackTrace.
Exception in thread "main" java.lang.NumberFormatException: null
	at java.base/java.lang.Integer.parseInt(Integer.java:614)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at com.example.task01.Test.convertStringToInt(Solution.java:10)
	at com.example.task01.Test.main(Solution.java:6)
Antes de que ocurriera el error, el programa profundizó en los métodos, pero tan pronto como ocurrió el error, todo comienza a suceder en orden inverso. Se imprime una línea que describe el problema (N° 1 en el ejemplo), luego se toma el último (y en la parte superior) valor agregado al nuestro, Стэкera el número cuatro y se imprime en la consola (N° 2 en el ejemplo) y vemos que el problema surgió en la clase Integeren la línea 614 de código y llamó a esta línea, línea 770 de un método parseIntde la misma clase (Nº 3 en el ejemplo) que al sumarle Стэкera el número tres y este método de clase, Integeraún no visible para nosotros, ya fue llamado por nuestro método convertStringToIntubicado en la línea 10 de nuestro programa (No. 4 en el ejemplo, y al agregarlo era el segundo), y este, a su vez, fue llamado mainen la línea 6 (No. 5 en el ejemplo, y al añadir, respectivamente, el primero). Entonces, al almacenar Стекnuestros métodos llamados paso a paso, pudimos regresar a mainla impresión paralela de la información que nos llevó exactamente al error. Pero StackTraceesto no es sólo trabajar con errores, sino que nos permite obtener mucha información interesante sobre el proceso de nuestra aplicación. Veamos otro ejemplo popular en los comentarios de la conferencia principal del nivel 9. Tenemos el código e inmediatamente le adjuntaré una imagen que visualiza el proceso del programa:
public class Test {
    public static void main(String[] args) {
        method1();
        method2();
    }
    public static void method1() {
        //не вызывает ничего
    }
    public static void method2() {
        method3();
        method4();
    }
    public static void method3() {
        //не вызывает ничего
    }
    public static void method4() {
        method5();
    }
    public static void method5() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        for (StackTraceElement element:stackTraceElements) {
            System.out.println(element.getMethodName());
        }
    }
}
Stack Trace y con qué se come - 2 Aquí nuestro programa hace su trabajo perfectamente y finaliza. Esto es lo que veremos en la salida de la consola:
getStackTrace
method5
method4
method2
main

Process finished with exit code 0
¿Cómo llegamos a esta conclusión y qué sucedió en el quinto método, a partir de la línea 20? Me temo que lo mejor que puedo hacer es agregar la explicación más popular (abreviada) del usuario Kirill de los comentarios de la conferencia. Pasemos a la línea de creación StackTracey analicémosla elemento por elemento:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]- una indicación del tipo de matriz (en los primeros niveles ya aprendiste sobre matrices como int[], String[], aquí es lo mismo). stackTraceElements- El nombre de la matriz puede ser cualquier cosa, teniendo en cuenta las reglas generales de nomenclatura, esto no afecta el trabajo. Thread.currentThread()- obtener un enlace al hilo actual en el que se ejecutan los métodos que queremos rastrear (por ahora esto no es importante, analizarás los hilos con más detalle en el nivel 16 en la misión Java Core) getStackTrace()- obtener todos Стэкlos métodos llamados ( Este es un captador normal para StackTrace) Ahora veamos qué puede resultarnos útil la matriz creada. Entendemos que la matriz almacena información sobre los métodos ejecutados. (c) Y para esto, en la línea 21 lanzamos un ciclo modificado forllamado forEach(por cierto, para aquellos que aún no han estudiado este ciclo, les aconsejo que lean sobre él) y enviamos datos de la matriz a la consola, es decir, información sobre qué métodos se ejecutaron durante el trabajo utilizando la construcción element.getMethodName(). Atención, como vemos, el elemento cero del array resultó ser él mismo, getStackTrace()respectivamente, ya que al momento de recibir el array de datos fue el último método que se ejecutó y con ello terminó en la cima Стэка, y ​​recordando nuestra construcción” El último en entrar, el primero en salir ” es inmediatamente el primero que se agrega a la matriz bajo el elemento cero. Esto es lo que podemos obtener StackTraceElement: Cadena getClassName(): devuelve el nombre de la clase. Cadena getMethodName(): devuelve el nombre del método. Cadena getFileName(): devuelve el nombre del archivo (puede haber muchas clases en un archivo). Cadena getModuleName(): devuelve el nombre del módulo (puede ser nulo). Cadena getModuleVersion(): devuelve la versión del módulo (puede ser nula). int getLineNumber(): devuelve el número de línea del archivo en el que se llamó al método. Ahora que comprende el principio general de funcionamiento, le aconsejo que pruebe usted mismo diferentes métodos StackTraceen su Ide . Incluso si no lo dominas todo por completo, continúa aprendiendo y el rompecabezas resultará de la misma manera que me resultó a mí en este asunto. ¡Les deseo todo el éxito! PD: Si te gustó este material, apóyalo con un me gusta. No te resulta difícil, me alegro. Gracias y nos vemos en el nivel 41 ;)
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION