StackTrace

Открыта
StackTrace - 1

— Привет! Сегодня я расскажу тебе, что такое стек-трейс. Но сначала расскажу, что такое стек.

— Представь себе стопку бумаг — деловых поручений для некоторого исполнителя. Сверху на стопку можно класть новое задание, и с верха стопки задание можно брать. При таком подходе задания будут исполняться не по порядку поступления. Задание, положенное самым последним, будет взято исполнителем самым первым. Такая структура элементов коллекции называется стеком – стопкой.

В Java для этого есть специальная коллекция – Stack. Это коллекция, у которой есть методы «добавить элемент» и «взять(достать/забрать) элемент». Как ты уже догадался, первым будет взят элемент, добавленный самым последним.

— Хм. Вроде не сложно и понятно.

— Отлично. Тогда сейчас объясню, что такое стек-трейс.

— Представь себе, что в Java функция А вызвала функцию Б, а та вызвала функцию В, а та, в свою очередь, функцию Г. Так вот, чтобы выйти из функции Б, нужно сначала выйти из функции В, а для этого выйти из функции Г. Это очень похоже на стек.

— А чем похоже?

— В стопке тоже, чтобы добраться до какого-то листка с заданием, надо довыполнить все задания, которые положили сверху.

— Ну, некоторая аналогия есть, но не уверен, что я все понял правильно.

— Смотри. Стек – это набор элементов. Как листы в стопке. Чтобы взять третий сверху лист, надо сначала взять второй, а для этого взять первый. Класть и брать листы можно всегда, но всегда взять можно только самый верхний.

— С вызовом функций то же самое. Функция А вызывает функцию Б, а та вызывает функцию В. И чтобы выйти из А, надо сначала выйти из Б, а для этого надо выйти из В.

— Подожди. Если я все правильно понял, то весь этот стек сведется к «взять можно только самый последний положенный лист», «выйти можно только из последней функции, в которую зашли». Так?

— Да. Так вот – последовательность вызовов функций — это и есть «стек вызовов функций», он же просто «стек вызовов». Функция, вызванная последней, должна завершиться самой первой. Давай посмотрим это на примере:

Получение и вывод текущего стека вызовов:
public class ExceptionExample
{
  public static void main(String[] args)
  {
    method1();
  }

  public static void method1()
  {
    method2();
  }

  public static void method2()
  {
    method3();
  }

  public static void method3()
  {
    StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
    for (StackTraceElement element : stackTraceElements)
    {
       System.out.println(element.getMethodName());
    }
  }
}
Вот какой результат мы получим:
getStackTrace
method3
method2
method1
main
2
Задача
Java Syntax,  9 уровень,  1 лекция
Недоступна
Набираем код
Иногда думать не надо, строчить надо! Как ни парадоксально звучит, порой пальцы «запоминают» лучше, чем сознание. Вот почему во время обучения в секретном центре JavaRush вы иногда встречаете задания на набор кода. Набирая код, вы привыкаете к синтаксису и зарабатываете немного материи. А ещё — боретесь с ленью.

— Ок. С вызовом функций похоже все понятно. А что это еще за StackTraceElement?

— Java-машина ведет запись всех вызовов функций. У нее есть для этого специальная коллекция – стек (Stack). Когда одна функция вызывает другую, Java-машина помещает в этот стек новый элемент StackTraceElement. Когда функция завершается этот элемент удаляется из стека. Таким образом, в этом стеке всегда хранится актуальная информация о текущем состоянии «стека вызовов функций».

— Каждый StackTraceElement содержит информацию о методе, который был вызван. В частности можно получить имя этого метода с помощью функции getMethodName.

— В примере выше ты можешь видеть демонстрацию этого дела:

1) Получаем «стек вызовов»:

2) Проходимся по нему с помощью цикла for-each. Надеюсь, ты его еще не забыл.

3) Печатаем в System.out имена методов.

— Интересная штука и, похоже, совсем не сложная. Спасибо, Риша!

Комментарии (89)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Viktor Gromov11 уровень
29 июля, 09:03
Оберните в синий, а то он будто сам с собой разговаривает "— Хм. Вроде не сложно и понятно."
Dmytro Kravchenko (skorpions2000)12 уровень, Александрия
7 июля, 12:19
может кто-то поделиться информацией в интернете, потому что как-то трудно дается)) задачки решаю но не до конца понимаю как это работает) например создаю вот это в каждом методе
StackTraceElement[] stackTraceElement = Thread.currentThread().getStackTrace();
StackTraceElement element = stackTraceElement[2];
и вывожу знаечение, в общем прокатывает. только почему везде второй элемент? не первый? и не нулевой?))) я так понимаю что в предыдущих лежат значения предыдущих функций, как-то слишком смутно
Алексей10 уровень, Минск
7 июля, 18:53
индекс [0] в этом массиве занимает сам метод getStackTrace(),  а [1] - тот метод, который вызывает две строчки из твоего поста
GigaMax12 уровень
18 мая, 18:18
Повторяем)
Алексей10 уровень, Минск
12 мая, 14:16
Позволю себе своими пятью копейками дополнить лекцию: Народ, обратите внимание на пример от Риши, в нем (!!!) массив StackTraceElement[] создается для наглядности и на практике этого делать не надо, потому что массив ИТАК неявно создаётся методом getStackTrace(), который сам себя включает в этот массив и принимает в нем индекс [0] Это я к тому чтобы в следующей лекции вы не имели в задачах лишнего головняка
Dmytro Kravchenko (skorpions2000)12 уровень, Александрия
7 июля, 12:21
приведи пример кода пожалуйста
Yaroslav Tikhonov14 уровень, Санкт-Петербург
29 апреля, 20:01
в "Грокаем алгоритмы" про стеки вызовов очень наглядно и с картинками
Ваня Бойко18 уровень, Киев
12 апреля, 14:33
Thread.currentThread() - получает ссылку на текущий поток. getStackTrace() - получает весь стек вызовов. В результате получаем мы массив StackTraceElement[].
эволюта23 уровень
3 апреля, 07:27
Охренительно объяснили, Шилдт просто нервно курит в сторонке... пошел гуглить и курить литературу.Еще полдня возни...
Павел22 уровень, Санкт-Петербург
3 апреля, 21:51
все норм, StackTraceElement - тут хранятся типо записи getMethodName - а тут мы их просто читаем. то есть мы не можем посмотреть на документ которого у нас нет. так вот, StackTraceElement - он нам дает документ, getMethodName - а этот чувак разрешает не только держать его у себя в руках но еще и посмотреть что там, и все по сути то
Maria Gregory15 уровень
25 марта, 23:02
Почему в выводе нет
getMethodName()
- ведь этот метод был вызван последним.
Павел22 уровень, Санкт-Петербург
3 апреля, 21:53
вот все норм, последний как положенно
Alexey Yagudin15 уровень, Санкт-Петербург
10 марта, 11:22
Класс называется: пример исключения. А остальное норм)))
Alexey Yagudin15 уровень, Санкт-Петербург
10 марта, 18:46
Потом становится понятно, почему)))
Михаил23 уровень, Москва
5 марта, 03:48
задачка "Набираем код" не работет че-то
Валерий17 уровень
7 марта, 07:39
Я сам с ней промучился. Проверил каждую букву, ошибок нет, а светится красным. В итоге скопировал код из статьи и тогда валидатор принял. Где была ошибка понять не могу.
Muerto25 уровень, Санкт-Петербург
9 марта, 19:08
Проверяйте построчно. Снизу выделяешь до второй строки Ctrl+x, Ctrl+z. Потом до третьей строки и т.д. Видно будет в какой строке ошибка. У меня в основном это пропадающие пробелы. Например for (StackTraceElement element : и подобные этому я всегда записываю как for (StackTraceElement element:.