我只是尝试了一些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
请有人澄清一下吗?
答案 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
类。尝试一下,将其从源中删除。