Класс StackWalker

public final class StackWalker
extends Object

Объект для обхода стека вызовов.

Метод walk открывает последовательный поток StackFrame для текущего потока и затем применяет заданную функцию к потоку StackFrame. Поток возвращает элементы стека в порядке от верхнего кадра, представляющего точку выполнения, в которой был сгенерирован стек, до нижнего кадра. Поток StackFrame закрывается при возвращении метода walk. Если попытка повторного использования закрытого потока IllegalStateException.

Параметры обхода стека объекта StackWalker определяют информацию о StackFrame объектах, которые будут возвращены. По умолчанию, кадры стека из API рефлексии и реализации классов скрыты скрыты, а объекты StackFrame содержат имя класса и имя метода, но не Class reference.

Объект StackWalker потокобезопасен. Несколько потоков могут совместно использовать один объект StackWalker для обхода собственного стека. Проверка разрешений выполняется при создании объекта StackWalker в соответствии с запрошенными параметрами. Дальнейшие проверки разрешений во время обхода стека не выполняются.

Примечание API:
Примеры

1. Чтобы найти первого вызывающего абонента, отфильтровав известный список классов реализации:

StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
     Optional<Class<?>> callerClass = walker.walk(s ->
         s.map(StackFrame::getDeclaringClass)
          .filter(interestingClasses::contains)
          .findFirst());

2. Чтобы сделать моментальный снимок 10 верхних кадров стека текущего потока:

List<StackFrame> stack = StackWalker.getInstance().walk(s ->
         s.limit(10).collect(Collectors.toList()));
за исключением случаев, когда указано обратное, передача аргумента null в конструктор или метод в этом классе StackWalker вызовет исключение NullPointerException.
С тех пор:
9

Вложенные классы

Модификатор и тип Класс Описание
static class  StackWalker.Option

Параметры обхода стека для настройки информации о кадре стека, полученной объектом StackWalker.

static interface  StackWalker.StackFrame

Объект StackFrame представляет собой вызов метода, возвращаемый StackWalker.

Методы

Модификатор и тип Метод Описание
void forEach​(Consumer<? super StackWalker.StackFrame> action)

Выполняет заданное действие для каждого элемента потока StackFrame текущего потока, обходя кадры стека сверху вниз, начиная с вызова этого метода forEach.

Class<?> getCallerClass()

Возвращает объект Class вызывающего абонента, который вызвал метод, вызвавший getCallerClass.

static StackWalker getInstance()

Возвращает экземпляр StackWalker.

static StackWalker getInstance​(StackWalker.Option option)

Возвращает экземпляр StackWalker с заданными параметрами, определяющими доступную информацию о кадрах стека.

static StackWalker getInstance​(Set<StackWalker.Option> options)

Возвращает экземпляр StackWalker с заданным options определяющим доступную информацию о кадрах стека.

static StackWalker getInstance​(Set<StackWalker.Option> options, int estimateDepth)

Возвращает экземпляр StackWalker с заданным options определяющим доступную информацию о кадрах стека.

<T> T walk​(Function<? super Stream<StackWalker.StackFrame>,​? extends T> function)

Применяет заданную функцию к потоку StackFrame для текущего потока, обходя кадры стека сверху вниз, начиная с вызова этого метода walk.

Методы, объявленные в классе java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Методы

getInstance

public static StackWalker getInstance()

Возвращает экземпляр StackWalker.

Этот StackWalker настроен на пропускание всех скрытых кадров стека и не сохраняет ссылку на класс.

Возвращает:
экземпляр StackWalker , настроенный на пропускание всех скрытых кадров стека и не сохраняющий ссылку на класс.

getInstance

public static StackWalker getInstance(StackWalker.Option option)

Возвращает экземпляр StackWalker с заданным параметром, определяющим доступную информацию о кадрах стека.

Если менеджер безопасности присутствует и заданный option включает Option.RETAIN_CLASS_REFERENCE, он вызывает его метод checkPermission для RuntimePermission("getStackWalkerWithClassReference").

Параметры:
option - stack walking option
Возвращает:
экземпляр StackWalker , настроенный с заданным параметром
Исключения:
SecurityException - если менеджер безопасности существует и его метод checkPermission отклоняет доступ.

getInstance

public static StackWalker getInstance(Set<StackWalker.Option> options)

Возвращает экземпляр StackWalker с заданным набором options , определяющим доступную информацию о кадрах стека. Если заданный набор options пуст, этот экземпляр StackWalker настроен на пропускание всех скрытых кадров и не сохраняет ссылку на класс.

Если менеджер безопасности присутствует и заданный набор options включает Option.RETAIN_CLASS_REFERENCE, он вызывает его метод checkPermission для RuntimePermission("getStackWalkerWithClassReference").

Параметры:
options - stack walking option
Возвращает:
экземпляр StackWalker , настроенный с заданными параметрами
Исключения:
SecurityException - если менеджер безопасности существует и его метод checkPermission отклоняет доступ.

getInstance

public static StackWalker getInstance(Set<StackWalker.Option> options,
                                      int estimateDepth)

Возвращает экземпляр StackWalker с заданным набором options , определяющим доступную информацию о кадрах стека. Если заданный набор options пуст, этот экземпляр StackWalker настроен на пропускание всех скрытых кадров и не сохраняет ссылку на класс.

Если менеджер безопасности присутствует и заданный набор options включает Option.RETAIN_CLASS_REFERENCE, он вызывает его метод checkPermission для RuntimePermission("getStackWalkerWithClassReference").

estimateDepth указывает на предполагаемое количество кадров стека, которые этот экземпляр StackWalker обработает. Это может использоваться StackWalker в качестве подсказки для размера буфера.

Параметры:
options - stack walking options
estimateDepth - Приблизительное количество кадров стека для обработки.
Возвращает:
экземпляр StackWalker , настроенный с заданными параметрами
Исключения:
IllegalArgumentException - если estimateDepth <= 0
SecurityException - если менеджер безопасности существует и его метод checkPermission отклоняет доступ.

walk

public <T> T walk(Function<? super Stream<StackWalker.StackFrame>,​? extends T> function)

Применяет заданную функцию к потоку StackFrame текущей нити, проходя от верхнего кадра стека, то есть от метода, вызывающего этот метод walk.

Поток StackFrame будет закрыт после возврата из этого метода. Если используется закрытый объект Stream<StackFrame>, будет выброшено исключение IllegalStateException.

Примечание API:
Например, чтобы найти первые 10 вызывающих кадров, сначала пропустив те кадры, чья объявляющая класс находится в пакете com.foo:
List<StackFrame> frames = StackWalker.getInstance().walk(s ->
    s.dropWhile(f -> f.getClassName().startsWith("com.foo."))
     .limit(10)
     .collect(Collectors.toList()));

Этот метод принимает функцию Function, принимающую поток Stream<StackFrame>, а не возвращает поток Stream<StackFrame> и не позволяет вызывающему методу напрямую манипулировать потоком. Виртуальная машина Java свободна переупорядочивать стек управления потока, например, посредством деоптимизации. Используя параметр Function, этот метод позволяет получить доступ к кадрам стека через устойчивый вид стека управления потока.

Параллельное выполнение фактически отключено, и выполнение потока будет происходить только в текущей нити.

Примечание реализации:
Реализация стабилизирует стек, закрепляя кадр, специфичный для прохода по стеку, и гарантирует, что проход по стеку выполняется над закрепленным кадром. При закрытии или повторном использовании объекта потока будет выброшено исключение IllegalStateException.
Параметры типа:
T - тип результата применения функции к потоку кадров стека.
Параметры:
function - функция, которая принимает поток кадров стека и возвращает результат.
Возвращает:
результат применения функции к потоку кадров стека.

forEach

public void forEach(Consumer<? super StackWalker.StackFrame> action)

Выполняет заданное действие для каждого элемента потока StackFrame текущей нити, проходя от верхнего кадра стека, то есть от метода, вызывающего этот метод forEach.

Этот метод эквивалентен вызову

walk(s -> { s.forEach(action); return null; });
Параметры:
action - действие, которое должно быть выполнено для каждого StackFrame потока текущей нити

getCallerClass

public Class<?> getCallerClass()

Получает объект Class вызывающего метода, который вызвал метод, вызвавший getCallerClass.

Этот метод фильтрует кадры рефлексии, MethodHandle и скрытые кадры, независимо от параметров SHOW_REFLECT_FRAMES и SHOW_HIDDEN_FRAMES, с которыми был настроен этот экземпляр StackWalker.

Этот метод должен вызываться, когда вызывающий кадр присутствует. Если он вызывается из самого нижнего кадра стека, будет выброшено исключение IllegalCallerException.

Этот метод выбрасывает UnsupportedOperationException если этот StackWalker не настроен с параметром RETAIN_CLASS_REFERENCE.

Примечание API:
Например, Util::getResourceBundle загружает набор ресурсов от имени вызывающего метода. Он вызывает getCallerClass для определения класса, метод которого вызвал Util::getResourceBundle. Затем он получает загрузчик классов этого класса и использует загрузчик для загрузки набора ресурсов. Класс вызывающего метода в данном примере - MyTool.
class Util {
     private final StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
     public ResourceBundle getResourceBundle(String bundleName) {
         Class<?> caller = walker.getCallerClass();
         return ResourceBundle.getBundle(bundleName, Locale.getDefault(), caller.getClassLoader());
     }
 }

 class MyTool {
     private final Util util = new Util();
     private void init() {
         ResourceBundle rb = util.getResourceBundle("mybundle");
     }
 }
Эквивалентный способ найти класс вызывающего метода, используя метод walk, выглядит следующим образом (фильтрация кадров рефлексии, MethodHandle и скрытых кадров, не показанных ниже):
Optional<Class<?>> caller = walker.walk(s ->
         s.map(StackFrame::getDeclaringClass)
          .skip(2)
          .findFirst());
Если метод getCallerClass вызывается из метода, являющегося нижним кадром стека, например, метода static public void main запускаемого java запуском или метода, вызванного нитью, присоединённой JNI, будет выброшено исключение IllegalCallerException.
Возвращает:
объект Class вызывающего метода, вызвавшего этот метод.
Исключения:
UnsupportedOperationException - если этот StackWalker не настроен с параметром Option.RETAIN_CLASS_REFERENCE.
IllegalCallerException - если нет кадра вызова, т.е. когда этот метод getCallerClass вызывается из метода, являющегося последним кадром в стеке.

© 1993, 2020, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StackWalker.html

Spec-Zone .ru
спецификации, руководства, описания, API