Компилятор Java-8 просматривает соответствующие объявления методов:
public void forEach(Consumer<? super T>
в интерфейсе Iterable<T>
public void accept(T t)
в интерфейсе Consumer<T>
public static String test(String)
в вашем классе Runner
Из всего этого следует, что Consumer<String>
подойдет.
Следовательно, он расширяет ссылку на метод Runner::test
на реализацию интерфейса Consumer<String>
, который делегирует методу test(String)
.
Строка
Arrays.asList(testArgs).forEach(Runner::test);
расширена до чего-то эквивалентного этому:
Arrays.asList(testArgs).forEach(new Consumer<String>() {
@Override
public void accept(String t) {
test(t);
}
});
На самом деле это не совсем то же самое, но использует некоторую оптимизацию JVM, чтобы избежать накладных расходов анонимного класса , Но погружение в эти детали JVM привело бы сюда слишком далеко.
Египет (бесплатное программное обеспечение)
KcacheGrind (GPL)
CodeViz (GPL)
Понимают , делает очень хорошее задание создания графов вызовов.
AstrГ©e является самым устойчивым и сложным инструментом там, по моему скромному мнению.