Элементы трассировки стека
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 = is native method = false filename = TraceDemo1.java line number = 83 class name = TraceDemo1 method name = main is native method = false Точка входа в исключительную ситуацию расположена в строке 15 программы TraceDemo1.java в классе C в методе с именем , являющимся специальным именем для методов инициализации экземпляров в виртуальной машине 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/.
Теги: стек