Элементы трассировки стека

Содержание

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/.

Теги: стек