在 Java 中是否有使用方法引用 JAVA 覆盖方法的任何简短形式?
Is there any short-form for overriding methods in Java with method references JAVA?
我一直遇到这样的情况,这真的很方便
component.addWindowListener() { new WindowListener() {
// quick overriding to make syntax less verbose
windowClosing(e) -> Foo::doFoo;
windowActivated(e) -> Foo::doFoo;
}
}
目前这主要是这样的:
component.addWindowListener() new WindowListener() {
@Override
public void windowClosing(WindowEvent e) {
Foo.doFoo(e);
}
@Override
public void windowActivated(WindowEvent e) {
Foo.doFoo(e);
}
}
方法引用指向某个函数的地方:
public static void doFoo(WindowEvent e) {
// does code
}
这可能吗?因为完全覆盖非功能性接口非常令人沮丧。
您可以编写自己的 class 来保存这些 lambda 并根据需要调用它们。如果您经常这样做,它可能会节省一些代码,但在您的示例中,您最终可能会得到更多的代码行。
没有这样的语言功能,但如果您必须如此频繁地实现一个接口以至于这种冗长变得相关,您可以编写自己的适配器。
例如,使用下面的适配器,您可以编写
f.addWindowListener(WindowAdapter.window()
.onClosing(ev -> ev.getWindow().dispose())
.onClosed(ev -> System.out.println("closed"))
);
或利用import static
的力量:
f.addWindowListener(window().onClosing(ev -> System.out.println("closing")));
所以,继续你的例子
f.addWindowListener(window().onClosing(Foo::doFoo).onActivated(Foo::doFoo));
适配器:
public class WindowAdapter implements WindowListener {
static Consumer<WindowEvent> NO_OP = ev -> {};
public static WindowAdapter window() {
return new WindowAdapter(NO_OP, NO_OP, NO_OP, NO_OP, NO_OP, NO_OP, NO_OP);
}
final Consumer<WindowEvent> opened, closing, closed,
iconified, deiconified, activated, deactivated;
public WindowAdapter(Consumer<WindowEvent> opened, Consumer<WindowEvent> closing,
Consumer<WindowEvent> closed, Consumer<WindowEvent> iconified,
Consumer<WindowEvent> deiconified, Consumer<WindowEvent> activated,
Consumer<WindowEvent> deactivated) {
this.opened = opened;
this.closing = closing;
this.closed = closed;
this.iconified = iconified;
this.deiconified = deiconified;
this.activated = activated;
this.deactivated = deactivated;
}
public WindowAdapter onOpened(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened==NO_OP? c: opened.andThen(c),
closing, closed, iconified, deiconified, activated, deactivated);
}
public WindowAdapter onClosing(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing==NO_OP? c: closing.andThen(c),
closed, iconified, deiconified, activated, deactivated);
}
public WindowAdapter onClosed(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed==NO_OP? c: closed.andThen(c),
iconified, deiconified, activated, deactivated);
}
public WindowAdapter onIconified(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed,
iconified==NO_OP? c: iconified.andThen(c), deiconified, activated, deactivated);
}
public WindowAdapter onDeiconified(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed, iconified,
deiconified==NO_OP? c: deiconified.andThen(c), activated, deactivated);
}
public WindowAdapter onActivated(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed, iconified,
deiconified, activated==NO_OP? c: activated.andThen(c), deactivated);
}
public WindowAdapter onDeactivated(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed, iconified,
deiconified, activated, deactivated==NO_OP? c: deactivated.andThen(c));
}
@Override public void windowOpened(WindowEvent e) { opened.accept(e); }
@Override public void windowClosing(WindowEvent e) { closing.accept(e); }
@Override public void windowClosed(WindowEvent e) { closed.accept(e); }
@Override public void windowIconified(WindowEvent e) { iconified.accept(e); }
@Override public void windowDeiconified(WindowEvent e) { deiconified.accept(e); }
@Override public void windowActivated(WindowEvent e) { activated.accept(e); }
@Override public void windowDeactivated(WindowEvent e) { deactivated.accept(e); }
}
在 之上构建,这是一个稍微简单一些的实现。 API 有点不同,但如果您愿意,您可以轻松添加所有 on*()
方法:
public class WindowListenerAdapter implements WindowListener {
private Map<Integer, Consumer<WindowEvent>> listeners = new HashMap<>();
public static WindowListenerAdapter adapter() {
return new WindowListenerAdapter();
}
public WindowListenerAdapter register(int eventId, Consumer<WindowEvent> listener) {
if (eventId < WindowEvent.WINDOW_FIRST || eventId > WindowEvent.WINDOW_LAST) {
throw new IllegalArgumentException("Invalid event id: " + eventId);
}
listeners.merge(eventId, listener, Consumer::andThen);
return this;
}
private void processEvent(WindowEvent e) {
listeners.getOrDefault(e.getID(), i -> {}).accept(e);
}
@Override
public void windowOpened(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowClosing(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowClosed(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowIconified(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowDeiconified(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowActivated(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowDeactivated(final WindowEvent e) {
processEvent(e);
}
}
并将其用作:
f.addWindowListener(adapter().register(WINDOW_CLOSING, Foo::doFoo)
.register(WINDOW_ACTIVATED, Foo::doFoo));
你甚至可以添加一个
public static WindowListenerAdapter forWindow(Window f) {
final WindowListenerAdapter adapter = adapter();
f.addWindowListener(adapter);
return adapter;
}
并将其用作:
forWindow(f).register(WINDOW_CLOSING, Foo::doFoo)
.register(WINDOW_ACTIVATED, Foo::doFoo);
或与
类似
public WindowListenerAdapter on(Window w) {
w.addWindowListener(this);
return this;
}
写入:
adapter().register(WINDOW_CLOSING, Foo::doFoo)
.register(WINDOW_ACTIVATED, Foo::doFoo)
.on(f);
在 Java 中是否有使用方法引用覆盖方法的任何简短形式?
在看JEP draft: Concise Method Bodies可能会有这样的:
component.addWindowListener(new WindowListener() {
public void windowClosing(e) -> Foo.doFoo(e);
public void windowActivated(e) -> Foo.doFoo(e);
});
和
component.addWindowListener(new WindowListener() {
public void windowClosing(e) = Foo::doFoo;
public void windowActivated(e) = Foo::doFoo;
});
这使用语法来说明如何
Concise method bodies avoid the line noise, and let you treat the
anonymous class almost like a family of lambdas:
第一个代码使用 lambda 表达式。第二个代码使用请求的 方法引用 .
虽然这不是解决方案,但它可能会成为一个解决方案。让我们敬请期待。
我一直遇到这样的情况,这真的很方便
component.addWindowListener() { new WindowListener() {
// quick overriding to make syntax less verbose
windowClosing(e) -> Foo::doFoo;
windowActivated(e) -> Foo::doFoo;
}
}
目前这主要是这样的:
component.addWindowListener() new WindowListener() {
@Override
public void windowClosing(WindowEvent e) {
Foo.doFoo(e);
}
@Override
public void windowActivated(WindowEvent e) {
Foo.doFoo(e);
}
}
方法引用指向某个函数的地方:
public static void doFoo(WindowEvent e) {
// does code
}
这可能吗?因为完全覆盖非功能性接口非常令人沮丧。
您可以编写自己的 class 来保存这些 lambda 并根据需要调用它们。如果您经常这样做,它可能会节省一些代码,但在您的示例中,您最终可能会得到更多的代码行。
没有这样的语言功能,但如果您必须如此频繁地实现一个接口以至于这种冗长变得相关,您可以编写自己的适配器。
例如,使用下面的适配器,您可以编写
f.addWindowListener(WindowAdapter.window()
.onClosing(ev -> ev.getWindow().dispose())
.onClosed(ev -> System.out.println("closed"))
);
或利用import static
的力量:
f.addWindowListener(window().onClosing(ev -> System.out.println("closing")));
所以,继续你的例子
f.addWindowListener(window().onClosing(Foo::doFoo).onActivated(Foo::doFoo));
适配器:
public class WindowAdapter implements WindowListener {
static Consumer<WindowEvent> NO_OP = ev -> {};
public static WindowAdapter window() {
return new WindowAdapter(NO_OP, NO_OP, NO_OP, NO_OP, NO_OP, NO_OP, NO_OP);
}
final Consumer<WindowEvent> opened, closing, closed,
iconified, deiconified, activated, deactivated;
public WindowAdapter(Consumer<WindowEvent> opened, Consumer<WindowEvent> closing,
Consumer<WindowEvent> closed, Consumer<WindowEvent> iconified,
Consumer<WindowEvent> deiconified, Consumer<WindowEvent> activated,
Consumer<WindowEvent> deactivated) {
this.opened = opened;
this.closing = closing;
this.closed = closed;
this.iconified = iconified;
this.deiconified = deiconified;
this.activated = activated;
this.deactivated = deactivated;
}
public WindowAdapter onOpened(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened==NO_OP? c: opened.andThen(c),
closing, closed, iconified, deiconified, activated, deactivated);
}
public WindowAdapter onClosing(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing==NO_OP? c: closing.andThen(c),
closed, iconified, deiconified, activated, deactivated);
}
public WindowAdapter onClosed(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed==NO_OP? c: closed.andThen(c),
iconified, deiconified, activated, deactivated);
}
public WindowAdapter onIconified(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed,
iconified==NO_OP? c: iconified.andThen(c), deiconified, activated, deactivated);
}
public WindowAdapter onDeiconified(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed, iconified,
deiconified==NO_OP? c: deiconified.andThen(c), activated, deactivated);
}
public WindowAdapter onActivated(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed, iconified,
deiconified, activated==NO_OP? c: activated.andThen(c), deactivated);
}
public WindowAdapter onDeactivated(Consumer<WindowEvent> c) {
Objects.requireNonNull(c);
return new WindowAdapter(opened, closing, closed, iconified,
deiconified, activated, deactivated==NO_OP? c: deactivated.andThen(c));
}
@Override public void windowOpened(WindowEvent e) { opened.accept(e); }
@Override public void windowClosing(WindowEvent e) { closing.accept(e); }
@Override public void windowClosed(WindowEvent e) { closed.accept(e); }
@Override public void windowIconified(WindowEvent e) { iconified.accept(e); }
@Override public void windowDeiconified(WindowEvent e) { deiconified.accept(e); }
@Override public void windowActivated(WindowEvent e) { activated.accept(e); }
@Override public void windowDeactivated(WindowEvent e) { deactivated.accept(e); }
}
在 on*()
方法:
public class WindowListenerAdapter implements WindowListener {
private Map<Integer, Consumer<WindowEvent>> listeners = new HashMap<>();
public static WindowListenerAdapter adapter() {
return new WindowListenerAdapter();
}
public WindowListenerAdapter register(int eventId, Consumer<WindowEvent> listener) {
if (eventId < WindowEvent.WINDOW_FIRST || eventId > WindowEvent.WINDOW_LAST) {
throw new IllegalArgumentException("Invalid event id: " + eventId);
}
listeners.merge(eventId, listener, Consumer::andThen);
return this;
}
private void processEvent(WindowEvent e) {
listeners.getOrDefault(e.getID(), i -> {}).accept(e);
}
@Override
public void windowOpened(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowClosing(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowClosed(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowIconified(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowDeiconified(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowActivated(final WindowEvent e) {
processEvent(e);
}
@Override
public void windowDeactivated(final WindowEvent e) {
processEvent(e);
}
}
并将其用作:
f.addWindowListener(adapter().register(WINDOW_CLOSING, Foo::doFoo)
.register(WINDOW_ACTIVATED, Foo::doFoo));
你甚至可以添加一个
public static WindowListenerAdapter forWindow(Window f) {
final WindowListenerAdapter adapter = adapter();
f.addWindowListener(adapter);
return adapter;
}
并将其用作:
forWindow(f).register(WINDOW_CLOSING, Foo::doFoo)
.register(WINDOW_ACTIVATED, Foo::doFoo);
或与
类似public WindowListenerAdapter on(Window w) {
w.addWindowListener(this);
return this;
}
写入:
adapter().register(WINDOW_CLOSING, Foo::doFoo)
.register(WINDOW_ACTIVATED, Foo::doFoo)
.on(f);
在 Java 中是否有使用方法引用覆盖方法的任何简短形式?
在看JEP draft: Concise Method Bodies可能会有这样的:
component.addWindowListener(new WindowListener() {
public void windowClosing(e) -> Foo.doFoo(e);
public void windowActivated(e) -> Foo.doFoo(e);
});
和
component.addWindowListener(new WindowListener() {
public void windowClosing(e) = Foo::doFoo;
public void windowActivated(e) = Foo::doFoo;
});
这使用语法来说明如何
Concise method bodies avoid the line noise, and let you treat the anonymous class almost like a family of lambdas:
第一个代码使用 lambda 表达式。第二个代码使用请求的 方法引用 .
虽然这不是解决方案,但它可能会成为一个解决方案。让我们敬请期待。