Элементы трассировки стека
Содержание
1 Введение
2 Пример работы стека
3 Исключительная ситуация: ссылка имеет значение null
4 Исключительная ситуация генерируется во время инициализации экземпляра
5 Ссылки
Введение
Стандартная библиотека Java имеет механизм для отображения трассировки стека, использующий метод Throwable.printStackTrace
. Этот метод используется для создания дампа контекста программы для не перехваченных исключительных ситуаций. Информация о трассировке выводится в поток System.err
или в указанный PrintStream
или PrintWriter
.
Новые возможности библиотеки предоставляют вам возможность программного доступа к трассировке стека. Вы можете извлечь массив объектов StackTraceElement
, каждый объект представляет единичный фрейм стека в трассировочной информации.
Пример работы стека
Новые возможности библиотеки предоставляют вам возможность программного доступа к трассировке стека. Вы можете извлечь массив объектов StackTraceElement
, каждый объект представляет единичный фрейм стека в трассировочной информации. Рассмотрим пример, чтобы понять, как это работает:
class A {
B bref;
void f() {
bref.g();
}
}
class B {
void g() {
}
}
class C {
String str;
int len = str.length();
}
public class TraceDemo1 {
// создать дамп единичного элемента трассировки стека
static void dumpTraceElement(StackTraceElement ste) {
System.err.println("filename = " + ste.getFileName());
System.err.println("line number = " + ste.getLineNumber());
System.err.println("class name = " + ste.getClassName());
System.err.println("method name = " + ste.getMethodName());
System.err.println("is native method = " + ste.isNativeMethod());
}
// создать дамп массива элементов трассировки стека,
// сначала самые последние по времени
static void dumpTrace(Throwable e) {
// отобразить исключительную ситуацию
System.err.println("Exception: " + e);
System.err.println();
// отобразить трассировку
StackTraceElement ste[] = e.getStackTrace();
for (int i = 0; i < ste.length; i++) {
dumpTraceElement(ste[i]);
System.err.println();
}
}
public static void main(String args[]) {
// вызвать A.f() и инициировать исключительную ситуацию
try {
A aref = new A();
aref.f();
} catch (Throwable e) {
// отобразить типовую трассировку стека
e.printStackTrace();
System.err.println();
// создать дамп трассировки стека в пользовательском формате
dumpTrace(e);
}
System.err.println();
System.err.println("==============================");
System.err.println();
// вызвать исключительную ситуацию при инициализации
try {
new C();
} catch (Throwable e) {
dumpTrace(e);
}
}
}
Исключительная ситуация: ссылка имеет значение null
В этом примере программа TraceDemo1
сначала вызывает метод A.f
. Этот метод, в свою очередь, вызывает B.g
. К сожалению, при вызове B.g
ссылка на объект B имеет значение null
. Это вызывает исключительную ситуацию.
Сначала программа отображает типовую трассировку стека, которая выглядит примерно так:
java.lang.NullPointerException
at A.f(TraceDemo1.java:5)
at TraceDemo1.main(TraceDemo1.java:61)
Затем отображается пользовательскую трассировку стека - с названием исключительной ситуации и последовательностью элементов StackTraceElements:
Exception: java.lang.NullPointerException
filename = TraceDemo1.java
line number = 5
class name = A
method name = f
is native method = false
filename = TraceDemo1.java
line number = 61
class name = TraceDemo1
method name = main
is native method = false
Обратите внимание, что имя файла, имя класса и имя метода первого StackTraceElement
ссылается на исключительную ситуацию. Исключительная ситуация происходит в строке 5 программы TraceDemo1.java
внутри метода A.f
.
Исключительная ситуация генерируется во время инициализации экземпляра
Вторая часть примера показывает, что происходит, когда исключительная ситуация генерируется во время инициализации экземпляра. В этом примере программа TraceDemo1
создает объект C. При создании экземпляра объекта C делается попытка получить длину строки str
. Однако, поскольку str
никогда явно не инициализировалась, ссылка на нее равна null
. Вот результат работы этой части программы:
Exception: java.lang.NullPointerException
filename = TraceDemo1.java
line number = 15
class name = C
method name = <init>
is native method = false
filename = TraceDemo1.java
line number = 83
class name = TraceDemo1
method name = main
is native method = false
Точка входа в исключительную ситуацию расположена в строке 15 программы TraceDemo1.java
в классе C в методе с именем <init>
, являющимся специальным именем для методов инициализации экземпляров в виртуальной машине Java.
Вы можете использовать способность StackTraceElement
реализовывать форматированные отчеты об исключительных ситуациях и собственные форматы журналов. Примером пользовательского формата ведения журнала является формат, ограничивающий трассировку стека до разумной глубины. Например, если есть 500 фреймов стека, вы, возможно, захотите сохранить первые десять и последние десять. Информация StackTraceElement
является частью сериализованного представления экземпляров класса Throwable
, поэтому она доступна для десериализованных объектов.
Ссылки
Дополнительная информация об элементах трассировки стека находится в описании класса StackTraceElement
на странице http://java.sun.com/j2se/1.4/docs/api/java/lang/StackTraceElement.html.
Также обратитесь к разделу 10.12 "Потоки и исключительные ситуации" в учебнике "Язык программирования Java(tm), третье издание" Arnold, Gosling и Holmes http://java.sun.com/docs/books/javaprog/thirdedition/.