Трассировка стека — это список вызовов методов для данной точкой программы. Вы наверняка неоднократно видели эту информацию, она отображается каждый раз, когда при выполнении Java-программы возникает неконтролируемые исключение.
В версиях, предшествующих Java SE 1.4, для получения текстового описания трассировки стека применялся метод printStackTrace() класса Throwable. Теперь разработчикам доступен метод getStackTrace() он возвращает массив объектов StackTraceElement, которые можно анализировать в программе. Например:
1 2 3 4 |
Throwable t = new Throwable(); StackTraceElement[] frames = t.getStackTrace(); for(StackTraceElement frame : frames) // анализ frame |
Класса StackTraceElement содержит методы, позволяющие получить имя файла, номер строки кода, а также имя класса и метода. Форматированную строку, содержащую эту информацию, предоставляет метод toString().
Высокопрофессиональное продвижение в 9 социальных сетях Вы можете получить с помощью SMM сервиса avi1.ru. Здесь можно найти не только качественные ресурсы, но и действительно низкие цены с часто предлагаемыми скидками.
В Java SE 5.0 был добавлен статический метод Thread.getAllStackTraces(), который позволяет получить трассировку стека для всех потоков. Следующий фрагмент кода демонстрирует его применение:
1 2 3 4 5 6 |
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces(); for(Thread t : map.keySet()) { StackTraceElement[] frames = map.get(t); analyze frames } |
Более подробные сведения о потоках и интерфейсе Map приведены в следующих уроках нашего блога.
Ниже показан код программы, которая выводит трассировку стека для рекурсивной функции вычисления факториала. Например, при вычислении factorial(3) вы получите следующие данные:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
factorial(3) : StackTraceTest.factorial(StackTraceTest.java:8) StackTraceTest.main(StackTraceTest.java:23) factorial(2) : StackTraceTest.factorial(StackTraceTest.java:8) StackTraceTest.factorial(StackTraceTest.java:14)StackTraceTest.main(StackTraceTest.java:23) factorial(1) : StackTraceTest.factorial(StackTraceTest.java:8) StackTraceTest.factorial(StackTraceTest.java:14) StackTraceTest.factorial(StackTraceTest.java:14) StackTraceTest.main(StackTraceTest.java:23) return 1 return 2 return 6 |
Вот пример программы которая отображает результаты трассировки стека для рекурсивного метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import java.util.*; public class StackTraceTest { /** * Вычисление факториала. * @param n Неотрицательное число * @return n! = 1 * 2 * ... * n */ public static int factorial(int n) { System.out.println("factorial(" +n+ ") : "); Throwable t = new Throwable(); StackTraceElement[] frames = t.getStackTrace(); for(StackTraceElement f : frames) System.out.println(f); int r; if(n<=1) r=1; else r=n*factorial(n-1); System.out.println("return "+r); return r; } public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.print("Enter n: "); int n = in.netxInt(); factorial(n); } } |