Eclipse - "иерархия открытых вызовов" прекращает поиск в лямбда-цепочке

Вот мой пример кода Java:

public class Test {

    public static void main(String[] args) {
        methodDepth0(
            ()->
                methodDepth1(
                    ()->
                        methodDepth2()
                )
        );
    }

    static Object methodDepth2() {
        return null;
    }

    interface MyIF {
        void call();
    }

    static void methodDepth0(MyIF myIf){
        myIf.call();
    }

    interface MyIF2 {
        void call();
    }

    static void methodDepth1(MyIF2 myIf2){
        myIf2.call();
    }
}

Когда я открываю иерархию вызовов метода methodDepth2() из Eclipse (4.4), open call hierarchy останавливает поиск следующего вызывающего абонента: open call hierarchy stop searching next caller method

То, что я ожидаю, похоже на открытие иерархии вызовов метода methodDepth1() которые отображаются до main метода. opening call hierarchy of method <code>methodDepth1()</code> which show until the <code>main</code> method

Ответ 1

Из того, что я могу сказать, отсутствие глубины иерархии вызовов связано с (повторной) оценкой кода во время выполнения. Это объясняется в 15.27.4. Оценка времени лямбда-выражений в спецификации языка Java.

Во время выполнения оценка выражения лямбда аналогична оценке выражения создания экземпляра класса, поскольку нормальное завершение создает ссылку на объект. Оценка лямбда-выражения отличается от исполнения лямбда-тела.

Ответ 2

Как ясно видно на второй картинке, Eclipse способен отслеживать иерархию вызовов посредством вызова метода myIf.call() внутри methodDepth0. Это правильно, потому что (внешний) лямбда реализует метод MyIF.call().

Тот факт, что тот же шаблон не работает на следующем уровне гнездования, выглядит как ошибка. Пожалуйста, рассмотрите вопрос об ошибке для JDT/UI. ТИА.

Заметим, что для lambdas, реализующих такие типы библиотек, как Consumer<T>, количество вызывающих абонентов в accept(T) в рабочей области может легко стать неуправляемым, подобно любой иерархии вызовов через, например, Runnable.run() но это doesn не вопрос общей полезности иерархии вызовов через лямбда.