1. Obtener un seguimiento de la pila
El lenguaje de programación Java ofrece muchas formas para que un programador obtenga información sobre lo que está sucediendo en un programa. Y no solo palabras.
Por ejemplo, después de compilar los programas C++, se convierten en un gran archivo lleno de código de máquina, y todo lo que está disponible para un programador en tiempo de ejecución es la dirección del bloque de memoria que contiene el código de máquina que se está ejecutando actualmente. No mucho, digamos.
Pero para Java, incluso después de compilar un programa, las clases siguen siendo clases, los métodos y las variables no desaparecen, y el programador tiene muchas formas de obtener información sobre lo que sucede en el programa.
Rastreo de pila
Por ejemplo, en un momento de la ejecución de un programa, puede averiguar la clase y el nombre del método que se está ejecutando actualmente. Y no solo un método: puede obtener información sobre toda la cadena de llamadas de método desde el método actual hasta el main()
método.
Una lista que consiste en el método actual, el método que lo invocó y el método que lo llamó, etc. se denomina seguimiento de pila . Puedes obtenerlo con esta declaración:
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
También puedes escribirlo en dos líneas:
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
currentThread()
El método estático de la Thread
clase devuelve una referencia a un Thread
objeto, que contiene información sobre el hilo actual, es decir, el hilo actual de ejecución. Aprenderá más sobre subprocesos en los niveles 17 y 18 de la búsqueda de Java Core .
Este Thread
objeto tiene un getStackTrace()
método, que devuelve una matriz de StackTraceElement
objetos, cada uno de los cuales contiene información sobre un método. En conjunto, todos estos elementos forman un rastro de pila .
Ejemplo:
Código |
---|
|
Salida de consola |
|
Como podemos ver en la salida de la consola del ejemplo, el getStackTrace()
método devolvió una matriz de tres elementos:
getStackTrace()
metodo de laThread
clasetest()
metodo de laMain
clasemain()
metodo de laMain
clase
A partir de este seguimiento de la pila, podemos concluir que:
- El
Thread.getStackTrace()
método fue llamado por elMain.test()
método en la línea 11 del archivo Main.java - El
Main.test()
método fue llamado por elMain.main()
método en la línea 5 del archivo Main.java - Nadie llamó al
Main.main()
método: este es el primer método en la cadena de llamadas.
Por cierto, solo parte de la información disponible se mostró en la pantalla. Todo lo demás se puede obtener directamente del StackTraceElement
objeto.
2.StackTraceElement
Como sugiere su nombre, la StackTraceElement
clase se creó para almacenar información sobre un elemento de seguimiento de la pila , es decir, un método en el archivo stack trace
.
Esta clase tiene los siguientes métodos de instancia:
Método | Descripción |
---|---|
|
Devuelve el nombre de la clase. |
|
Devuelve el nombre del método. |
|
Devuelve el nombre del archivo (un archivo puede contener varias clases) |
|
Devuelve el número de línea en el archivo donde se llamó al método |
|
Devuelve el nombre del módulo (puede ser null ) |
|
Devuelve la versión del módulo (puede ser null ) |
Pueden ayudarlo a obtener información más completa sobre la pila de llamadas actual:
Código | Salida de consola | Nota |
---|---|---|
|
|
nombre de clase nombre de método nombre de archivo número de línea nombre de módulo versión de módulo nombre de clase nombre de método nombre de archivo número de línea nombre de módulo versión de módulo nombre de clase nombre de método nombre de archivo número de línea nombre de módulo versión de módulo |
3. Apilar
Ya sabes qué es un seguimiento de pila , pero ¿qué es una pila (clase Stack)?
Una pila es una estructura de datos a la que puede agregar elementos y desde la cual puede recuperar elementos. Al hacerlo, solo puede tomar elementos del final: primero toma el último agregado, luego el penúltimo agregado, etc.
La pila de nombres en sí sugiere este comportamiento, como la forma en que interactuaría con una pila de papeles. Si coloca las hojas 1, 2 y 3 en una pila, debe recuperarlas en orden inverso: primero la tercera hoja, luego la segunda y solo luego la primera.
Java incluso tiene una clase especial de colección Stack con el mismo nombre y comportamiento. Esta clase comparte muchos comportamientos con ArrayList
y LinkedList
. Pero también tiene métodos que implementan el comportamiento de la pila:
Métodos | Descripción |
---|---|
|
Agrega el obj elemento a la parte superior de la pila. |
|
Toma el elemento de la parte superior de la pila (la profundidad de la pila disminuye) |
|
Devuelve el elemento en la parte superior de la pila (la pila no cambia) |
|
Comprueba si la colección está vacía. |
|
Busca un objeto en la colección y devuelve suindex |
Ejemplo:
Código | Contenido de la pila (la parte superior de la pila está a la derecha) |
---|---|
|
|
Las pilas se utilizan con bastante frecuencia en la programación. Así que esta es una colección útil.
4. Mostrar un seguimiento de la pila durante el manejo de excepciones
¿ Por qué una lista de llamadas a métodos se denomina seguimiento de pila ? Porque si piensa en la lista de métodos como una pila de hojas de papel con nombres de métodos, cuando llama al siguiente método, agrega una hoja con el nombre de ese método a la pila. Y la siguiente hoja de papel va encima de eso, y así sucesivamente.
Cuando finaliza un método, se elimina la hoja en la parte superior de la pila. No puede quitar una hoja del medio de la pila sin quitar todas las hojas que están encima. De manera similar, no puede terminar un método en medio de una cadena de llamadas sin terminar todos los métodos que ha llamado.
Excepciones
Otro uso interesante para las pilas es durante el manejo de excepciones.
Cuando ocurre un error en un programa y se lanza una excepción , la excepción contiene el seguimiento de la pila actual : una matriz que consta de una lista de métodos que comienzan, desde el método principal y terminan con el método donde ocurrió el error. ¡Incluso está la línea donde se lanzó la excepción!
Este seguimiento de la pila se almacena dentro de la excepción y se puede recuperar fácilmente mediante el siguiente método:StackTraceElement[] getStackTrace()
Ejemplo:
Código | Nota |
---|---|
|
Capturar la excepción Obtenga el seguimiento de la pila que existía cuando ocurrió el error. |
Este es un método de la Throwable
clase, por lo que todos sus descendientes (es decir, todas las excepciones) tienen el getStackTrace()
método. Súper conveniente, ¿eh?
Mostrar el seguimiento de la pila de la excepción
Por cierto, la Throwable
clase tiene otro método para trabajar con seguimientos de pila, un método que muestra toda la información de seguimiento de pila almacenada dentro de la excepción. se llama printStackTrace()
.
Muy convenientemente, puede llamarlo en cualquier excepción.
Ejemplo:
Código |
---|
|
Salida de consola |
|
GO TO FULL VERSION