具有函数接口的Java-8 lambda表达式行为

具有函数接口的Java-8 lambda表达式行为,java,functional-programming,java-8,lambda,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() {

我只是在尝试一些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);
    }
}
我的问题是,在执行第4行的过程中,Java如何理解创建
instanceof
Open并将其添加到宏中。简而言之,lamdba表达式的行为方式与第5行相同。使用lambda表达式,整个模式变得简单得多,但是使用面向对象的函数式编程会使开发变得非常抽象还是更不冗长

问题提供:O'Reilly媒体:Java 8 Lamdbas


任何人都可以澄清这一点吗?

Lambda构造是一个非常可读的替代品,它是Java语言的一个长期组成部分:匿名类。事实上,关于意图,您可以将lambda表达式看作是一个匿名类,尽管在技术上有很大的区别

只需为
记录方法添加第三个变量:

macro.record(new Action() {
    @Override public void perform() { editor.open(); }
});
在这里,您将一个匿名类(Action的子类)的实例传递给recording方法。这与lambda表达式相同:

macro.record(() -> editor.open());
对于这两个变体,您甚至不需要
Open
类。尝试一下并从源代码中删除它

Java如何理解创建OpenInstanceof并将其添加到宏中

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

macro.record(() -> editor.open());
您没有创建开放类的实例。您没有创建生成的匿名类的实例

请参阅中的
翻译策略
部分

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


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

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

最后,您可以删除
操作
界面并使用该界面。例如,这允许使用
java.util.concurrent
的所有内容,比如新的java承诺:…

耶!这就是我要找的,谢谢(:是的,我真的很喜欢方法引用。java 8在不失去简单性的情况下引入了很多很棒的东西。java发行量越大,我支持你,我可以说这种混合让java更可编程,当然对开发人员也更友好。完全披露:我是java 8 Lambdas的作者。我对这个答案投了赞成票,而不是加入我自己的bec因为我认为这是一个非常好的答案!如果你想更详细地理解目标类型,那么可能值得阅读从第11页开始的“类型推断”一节。
    Editor editor= new MyEditor();
    Macro macro = new Macro();
    macro.record(editor::open);
    macro.record(editor::close);
    macro.run();