Страницы

Поиск по вопросам

суббота, 13 октября 2018 г.

Как данный код на stream может компилироваться и работать?

Как данный код может выполняться и компилироваться если при action.perform, метод perform даже не определен. И плюс команда типа editor в момент m.record(editor::save);, а сам список macro преназначен для объектов типа action? Как такое может быть?
public class Macro { List macro;
Macro(){ macro = new ArrayList<>(); }
public void record(Actiona action){ macro.add(action); }
public void run(){ macro.forEach(Actiona::perform); }
public static void main(String[] args) { MockEditor editor = new MockEditor(); Macro m = new Macro(); m.record(editor::save); m.record(editor::close); m.run(); } }
public class MockEditor implements Editor {
@Override public void save() { System.out.println("Save"); }
@Override public void close() { System.out.println("close"); } }
public interface Actiona { public void perform(); }
public interface Editor { public void save(); public void close(); }


Ответ

Эту магию легко понять, если пойти в IDE (скажем IDEA) и попросить заменить лямду на анонимный класс:
public static void main(String[] args) { MockEditor editor = new MockEditor(); Macro m = new Macro();
m.record(new Actiona() { // вместо m.record(editor::save); @Override public void perform() { editor.save(); } });
m.record(new Actiona() { // вместо m.record(editor::close); @Override public void perform() { editor.close(); } });
m.run(); // Вызываем метод с двумя объектами Actiona
И неожиданно все становится простым и понятным, мы реализуем метод perform вызывая внутри методы editor.save() и editor.close(), так что поведение вполне корректное.
Очень хорошое умение, как только запутался в ламбда-функциях, заменяй их мысленно (или с помощью IDE) на анонимные классы и жить становится проще.

Комментариев нет:

Отправить комментарий