在Java中,可以使用lambda而不是匿名类优雅地实现具有单个抽象方法的接口(即SAM类型或功能接口):
// SAM ActionListener with anonymous implementation
button.addActionListener(
new ActionListener(){
public void actionPerformed(Event e){
System.out.println("button via anon!");
}
}
);
可以替换为:
// SAM ActionListener with lambda implementation
button.addActionListener(
e -> System.out.println("button via lambda!")
);
但是对于具有多种抽象方法的接口,lambda无法直接应用。例如,java.awt.event.WindowListener
有七个方法。但是通常一大段代码只对定义这七个方法之一感兴趣。
要使用匿名类重写来实现该行为,我们可以:
// non-SAM with adapter implementation with override
window.addWindowListener(
new WindowAdapter() {
@Override
public void windowOpened(Event e){
System.out.println("WindowAdapter opened via override!");
}
}
);
但是lambdas是否有更优雅的方式?
@FunctionalInterface
public interface ActionListener {
void actionPerformed(Event e);
}
public interface WindowListener {
void windowOpened(Event e);
void windowClosing(Event e);
}
public class WindowAdapter implements WindowListener {
public void windowOpened(Event e){
System.out.println("windowOpened in adapter!");
}
public void windowClosing(Event e){
System.out.println("windowClosing in adapter!");
}
}
注意 :@ maythesource.com提出了一个类似但更广泛的问题:“
如果某人想要在匿名类中实现多个方法,该如何处理MouseListener?
”最受支持和接受的答案是使用匿名实现。我的问题是有关非SAM类型的优雅lambda解决方案。
我发现的最优雅的方法是使用匿名桥:
// SAM bridge with lambda implementation
window.addWindowListener(
WindowBridge.windowOpened(
b -> System.out.println("opening via lambda!")
)
);
与SAM类型的情况类似,它比匿名适配器还干净:
// non-SAM with adapter implementation with override
window.addWindowListener(
new WindowAdapter() {
@Override
public void windowOpened(Event e){
System.out.println("WindowAdapter opened via override!");
}
}
);
但是它确实需要带有静态工厂的桥,这有点尴尬:
import java.util.function.Consumer;
public interface WindowBridge {
// SAM for this method
public abstract class WindowOpened extends WindowAdapter {
public abstract void windowOpened(Event e);
}
// factory bridge
public static WindowOpened windowOpened(Consumer<Event> c) {
return new WindowOpened() {
public void windowOpened(Event e){
c.accept(e);
}
};
}
// SAM for this method
public abstract class WindowClosing extends WindowAdapter {
public abstract void windowClosing(Event e);
}
// factory bridge
public static WindowClosing windowClosing(Consumer<Event> c) {
return new WindowClosing() {
public void windowClosing(Event e){
c.accept(e);
}
};
}
}
在Java中,具有单个抽象方法的接口(即SAM类型或函数接口)可以用lambda而不是匿名类优雅地实现: 可替换为: 但对于具有多个抽象方法的接口,则不能直接应用lambda。例如,有七个方法。但通常一个块代码只对定义这七个方法中的一个感兴趣。 注意:@maythesource.com问了一个类似但更广泛的问题:“如果有人想在匿名类中实现多个方法,他们会如何处理MouseListener?”最受欢
我已经为使用者接口尝试了类似这样的lambda表达式,它没有问题。其他一些lambda表达式不起作用,因为它们返回一些东西,如。 编译和执行没有问题。 所以我遇到的问题是,我认为像这样的lambda表达式总是等效于,所以我希望编译器会给我一个错误,因为您不能从使用者接口返回(或任何其他类型)。显然,编译器正在将lambda表达式转换为一个方法,如果没有return语句,并且调用方法而不实际返回值。
问题内容: 我试图了解Java的行为。使用此接口: 我正在重载这样的方法: 当使用以下对象调用方法时: Java为什么使用: 代替 ? 谢谢 问题答案: 因为编译器只知道是的实例。在编译时根据所涉及表达式的编译时类型确定重载,并且is 的编译时类型为。 (将此与覆盖进行比较,在覆盖时,将根据所涉及的实际类型在 执行 时选择方法实现。)
问题内容: 我正在学习如何使用JavaScript进行OOP。它具有接口概念(例如Java的接口)吗? 这样我就可以创建一个侦听器… 问题答案: 没有“此类必须具有这些功能”的概念(也就是说,本身没有接口),因为: JavaScript继承基于对象,而不是类。除非您意识到:这不是什么大不了的事情 JavaScript是一种 非常 动态的类型化语言-您可以使用适当的方法创建对象,这将使其符合接口,
问题内容: 根据Hibernate文档的这一部分,我应该能够查询HQL中的任何Java类。 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html#queryhql- polymorphism 不幸的是,当我运行此查询时… 我收到消息“未映射事务[[从事务trans,其中trans.envelopeId =:
问题内容: 好的,这是我的问题: 我有一个包含interfaces的列表-和扩展该接口的接口的列表:。我要设置。我不希望使用任何东西或会花费更多内存的东西,因为我正在做的事情已经非常耗费成本。我确实需要能够说。我已经尝试过,但是后来我无法将接口添加到列表中,只能将SubInterfaces 添加到列表中。有什么建议? 我希望能够做这样的事情: RecordKeeper类是包含接口列表的类(NOT