[英]Java-8 lambda expressions behaviour with functional Interface
I was just trying out few java-8 functional programming , I had few doubts on the behaviour of the lamda expressions. 我只是尝试了几个java-8函数式编程,我对lamda表达式的行为几乎没有怀疑。 I have tried to explain the problem below with simple Command Pattern.
我试图通过简单的命令模式来说明以下问题。
public interface Editor {
public void open();
public void close();
// public void save();
}
Editor Implementation 编辑器实施
public class MyEditor implements Editor {
@Override
public void open() {
System.out.println("...opening");
}
@Override
public void close() {
System.out.println("...closing");
}
}
Interface Action 界面动作
// this is actually a @FunctionalInterface
public interface Action {
public void perform();
}
Actionable items. 可行的物品。
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...
... ...
A Macro to run all the actions. 用于运行所有操作的宏。
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);
}
}
Now running the Macro is where the interesing part is . 现在,运行宏是交互部分所在的位置。
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();
}
}
My question is , during the execution of Line 4, How does Java understand that to create a instanceof
Open and add it into macro. 我的问题是,在第4行的执行过程中,Java如何理解创建
instanceof
并将其添加到宏中。 In short lamdba expressions is behaving same way as Line 5. This whole pattern becomes a lot simpler with lambda expressions BUT does the functional programming with OOPS makes the development at very abstract level or less verbose? 简而言之,lamdba表达式的行为方式与第5行相同。使用lambda表达式,整个模式变得更加简单但是,使用OOPS进行功能编程是否会使开发变得非常抽象或不太冗长?
Courtesy of problem : O'Reilly Media : Java 8 Lamdbas 问题的礼貌:O'Reilly媒体:Java 8 Lamdbas
Could any one please clarify this.? 有人可以澄清一下吗?
How does Java understand that to create a instanceof Open and add it into macro ?
Java如何理解如何创建Open的实例并将其添加到宏中?
You should read the section Target Typing in Lambda Expressions of the java tutorial. 您应该阅读Java教程的Lambda表达式中的目标类型部分。 When you wrote:
你写的时候:
macro.record(() -> editor.open());
Your are not creating an instance of the Open class. 您没有创建Open类的实例。 You are not creating an instance of a generated anonymous class.
您没有创建生成的匿名类的实例。
See Translation strategy
section in Translation of Lambda Expressions . 请参阅Lambda表达式的翻译中的
Translation strategy
部分。
Instead of generating bytecode to create the object that implements the lambda expression (such as calling a constructor for an inner class), we describe a recipe for constructing the lambda, and delegate the actual construction to the language runtime.
我们不是生成字节码来创建实现lambda表达式的对象(例如调用内部类的构造函数),而是描述构造lambda的配方,并将实际构造委托给语言运行库。 That recipe is encoded in the static and dynamic argument lists of an invokedynamic instruction.
该配方在invokedynamic指令的静态和动态参数列表中进行编码。
You could also take advantages of the java 8 method references , and simplify again the code: 您还可以利用java 8 方法引用 ,并再次简化代码:
Editor editor= new MyEditor();
Macro macro = new Macro();
macro.record(editor::open);
macro.record(editor::close);
macro.run();
at last you may remove the Action
interface and use the Runnable
one. 最后,您可以删除
Action
界面并使用Runnable
界面。 This allow for example to use all the stuff of the java.util.concurrent
like Executor , the new java promise: CompletableFuture
... 例如,这允许使用
java.util.concurrent
所有内容,例如Executor ,新的Java承诺: CompletableFuture
...
Lambda constructs are a very readable replacement for a construct that is a long-time part of the Java language: anonymous classes . Lambda构造是Java语言中长期存在的构造: 匿名类的一种非常易读的替代。 In fact, regarding the intention you can think of a lambda expression as an anonymous class, although technically there is a big difference.
实际上,就技术意图而言,您可以将lambda表达式视为一个匿名类,尽管在技术上存在很大差异。
Just to add a third variant for your record
method: 只是为您的
record
方法添加第三个变体:
macro.record(new Action() {
@Override public void perform() { editor.open(); }
});
Here you are passing an instance of an anonymous class (a subclass of Action
) to the recording method. 在这里,您将一个匿名类(
Action
的子类)的实例传递给记录方法。 This is the same with the lambda expression: 这与lambda表达式相同:
macro.record(() -> editor.open());
For these two variants you even do not need the Open
class. 对于这两个变体,您甚至不需要
Open
类。 Try it out and remove it from the sources. 尝试一下,将其从源中删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.