具有功能接口的Java-8 lambda表达式行为

时间:2014-09-24 07:32:27

标签: java functional-programming java-8 lambda

我只是尝试了一些java-8函数式编程,我对lamda表达式的行为几乎没有怀疑。我试图用简单的命令模式解释下面的问题。

public interface Editor {
    public void open();
    public void close();
//  public void save();

}

编辑实施

public class MyEditor implements Editor {

    @Override
    public void open() {
        System.out.println("...opening");

    }

    @Override
    public void close() {
        System.out.println("...closing");
    }

}

界面操作

// this is actually a @FunctionalInterface
public interface Action {
    public void perform();

}

可行的物品。

public class Open implements Action {

    private final Editor editor;

    public Open(Editor editor) {
        this.editor = editor;
    }

    @Override
    public void perform() {
        editor.open();
    }

// Similarly Close implements Action...

...

用于运行所有操作的宏。

public class Macro {

    private final List<Action> actions;

    public Macro() {
        actions = new ArrayList<>();
    }

    public void record(Action action) {
        actions.add(action);
    }

    public void run() {
        actions.forEach(Action::perform);
    }
}

现在运行宏是有意义的部分。

public class RunMacro {
    public static void main(String[] args) {
        Editor editor= new MyEditor();
        Macro macro = new Macro();
        macro.record(() -> editor.open());// Line 4
        macro.record(new Close(editor));  // Line 5
        macro.run();
    }
}

我的问题是,在第4行的执行过程中,Java如何理解创建instanceof Open并将其添加到宏中。简而言之,lamdba表达式的行为与第5行相同。使用lambda表达式,整个模式变得更简单。使用OOPS进行函数式编程是否使得开发处于非常抽象的级别或更简洁?

礼貌问题:O'Reilly Media:Java 8 Lamdbas

请有人澄清一下吗?

2 个答案:

答案 0 :(得分:7)

  

Java如何理解创建Openof实例并将其添加到宏中?

您应该阅读java教程的Target Typing中的Lambda Expressions部分。 当你写道:

macro.record(() -> editor.open());

您没有创建Open类的实例。您没有创建生成的匿名类的实例。

请参阅Translation of Lambda Expressions中的Translation strategy部分。

  

我们不是生成字节码来创建实现lambda表达式的对象(例如调用内部类的构造函数),而是描述构造lambda的配方,并将实际构造委托给语言运行库。该配方在invokedynamic指令的静态和动态参数列表中进行编码。


您还可以利用java 8 method references,并再次简化代码:

    Editor editor= new MyEditor();
    Macro macro = new Macro();
    macro.record(editor::open);
    macro.record(editor::close);
    macro.run();

最后,您可以删除Action界面并使用Runnable界面。这允许例如使用java.util.concurrent的所有内容,例如Executor,新的java承诺:CompletableFuture ......

答案 1 :(得分:0)

Lambda构造是构造的一种非常可读的替代品,该构造是Java语言的长期组成部分:匿名类。事实上,关于意图,你可以将lambda表达式看作一个匿名类,虽然从技术上来说存在很大的差异。

只需为record方法添加第三个变体:

macro.record(new Action() {
    @Override public void perform() { editor.open(); }
});

这里,您将一个匿名类(Action的子类)的实例传递给录制方法。这与lambda表达式相同:

macro.record(() -> editor.open());

对于这两个变体,您甚至不需要Open类。尝试一下,将其从源中删除。