【问题标题】:Java 8 Lambda Expressions - what about multiple methods in nested classJava 8 Lambda 表达式 - 嵌套类中的多个方法怎么样
【发布时间】:2014-03-17 00:17:27
【问题描述】:

我正在阅读有关新功能的信息:http://www.javaworld.com/article/2078836/java-se/love-and-hate-for-java-8.html

我看到了下面的例子:

使用匿名类:

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        System.out.println("Action Detected");
    }
});

使用 Lambda:

button.addActionListener(e -> {
    System.out.println("Action Detected");
});

如果有人想在匿名类中实现多个方法,他们会用MouseListener 做什么,例如:

public void mousePressed(MouseEvent e) {
    saySomething("Mouse pressed; # of clicks: "
               + e.getClickCount(), e);
}

public void mouseReleased(MouseEvent e) {
    saySomething("Mouse released; # of clicks: "
               + e.getClickCount(), e);
}

...等等?

【问题讨论】:

  • 那么你只能使用匿名类。 lambda 的引入并没有使它们被弃用。 Lambda 只能与函数式接口一起使用。
  • 将 lambdas 用作 ActionListener 方法很奇怪。你怎么知道,你正在实现接口ActionListener的方法actionPerformed?!
  • @bobbel 这就是功能接口的全部概念,我建议您在评论它们之前阅读它们。
  • @maythesource.com 您可以创建两个额外的接口,例如MousePressedListenerMouseReleasedListener 以及两个方法addMousePressedListener(Button, MousePressedListener)addMouseReleasedListener(Button, MouseReleasedListener)。然后您可以使用 lambdas 来实现这些事件处理程序。
  • @maythesource.com 甚至更好:你只需要实现addMousePressedListener(Button, Consumer<MouseEvent>)addMouseReleasedListener(Button, Consumer<MouseEvent>)这两个方法,而不必提供不必要的接口。

标签: java lambda java-8 anonymous-class


【解决方案1】:

来自JLS 9.8

函数式接口是只有一个抽象方法的接口,因此 表示单个函数合约。

Lambda 需要这些函数式接口,因此仅限于它们的单一方法。实现多方法接口仍然需要使用匿名接口。

addMouseListener(new MouseAdapter() {

    @Override
    public void mouseReleased(MouseEvent e) {
       ...
    }

    @Override
    public void mousePressed(MouseEvent e) {
      ...
    }
});

【讨论】:

  • 来自 OP 的问题是“如果有人想在匿名类中实现多个方法,他们会用 MouseListener 做什么,例如:”(强调我的)。您给出的答案很好,但只是说您不能使用包含多个方法的接口进行 lambda 描述。 Holger's answer 解释了一个解决方法。您扩展至您自己的接口,并为您不想要的方法提供默认值。这为您的 lambda 留下了一个。 这不会是人们在 Java 8 代码中看到的第一个令人畏惧的东西。
【解决方案2】:

您可以通过辅助接口将多方法接口与 lambda 一起使用。这适用于不需要的方法的实现很简单的监听器接口(即我们也可以做MouseAdapter 提供的东西):

// note the absence of mouseClicked…
interface ClickedListener extends MouseListener
{
    @Override
    public default void mouseEntered(MouseEvent e) {}

    @Override
    public default void mouseExited(MouseEvent e) {}

    @Override
    public default void mousePressed(MouseEvent e) {}

    @Override
    public default void mouseReleased(MouseEvent e) {}
}

您只需要定义一次这样的帮助接口。

现在您可以像这样为Component c 添加点击事件监听器:

c.addMouseListener((ClickedListener)(e)->System.out.println("Clicked !"));

【讨论】:

  • 在我看来,这对于 MouseListeners 来说是一个洛可可式的解决方案。我认为附加匿名对象[旧方式]效果更好。在我看来,这是一个杂牌。
  • @ncmathsadist:如果您愿意,请随意使用匿名内部类方法。这只是一种选择。你也可以考虑this answer。还有the other dynamic listener generator
  • 我相信这个“​​kludge”应该是公认的答案。来自 OP 的问题显然是“如果有人想在匿名类中实现多个方法,例如:”(强调我的),他们会用 MouseListener 做什么。他问的是当你有一个包含多个方法的接口时如何使用 lamdas。 @Holger 完美地回答了这个问题。 OP 显然已经知道如何以非功能方式使用匿名类。
  • @Holger 在这四个中,当我们使用 lambda 时会调用哪个方法?因为所有这些方法都有相同的参数。
  • @dreamcoder 这四种方法都不会由 lambda 实现,因为它们都不是抽象的。 lambda 将实现mouseClicked 方法,该方法已在MouseListener 接口中声明为抽象方法,并且不会被ClickedListener 接口覆盖(因此得名)。
【解决方案3】:

Lambda EG 确实考虑过这个问题。许多库使用函数式接口,即使它们是在函数式接口成为事物之前几年设计的。但有时确实会发生一个类有多个抽象方法,而您只想使用 lambda 来定位其中一个。

这里官方推荐的模式是定义工厂方法:

static MouseListener clickHandler(Consumer<MouseEvent> c) { return ... }

这些可以直接由 API 自己完成(这些可以是 MouseListener 中的静态方法),或者如果维护者选择不提供这种便利,也可以是其他库中的外部辅助方法。因为需要这样做的情况很少,而且解决方法也很简单,所以进一步扩展语言来挽救这种极端情况似乎并不令人信服。

ThreadLocal 采用了类似的技巧;请参阅新的静态工厂方法withInitial(Supplier&lt;S&gt;)

(顺便说一下,当这个问题出现时,示例几乎总是MouseListener,这令人鼓舞,因为它表明希望对 lambda 友好但不是的类集实际上非常小.)

【讨论】:

  • 另见this question。还有一些其他的多方法接口,例如WindowListener,但数量相对较少。
【解决方案4】:

Java ActionListener 必须只实现一个方法 (actionPerformed(ActionEvent e))。这非常适合 Java 8 function,因此 Java 8 提供了一个简单的 lambda 来实现 ActionListener

MouseAdapter 至少需要两种方法,因此不适合作为function

【讨论】:

    【解决方案5】:

    我创建了允许我编写(单行)lambda 函数侦听器的适配器类,即使原始侦听器接口包含多个方法。

    注意 InsertOrRemoveUpdate 适配器,它将 2 个事件合并为一个。

    我的原始类还包含 WindowFocusListener、TableModelListener、TableColumnModelListener 和 TreeModelListener 的实现,但这使代码超过了 30000 个字符的 SO 限制。

    import java.awt.event.*;
    import java.beans.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import org.slf4j.*;
    
    public class Adapters {
      private static final Logger LOGGER = LoggerFactory.getLogger(Adapters.class);
    
      @FunctionalInterface
      public static interface AdapterEventHandler<EVENT> {
        void handle(EVENT e) throws Exception;
    
        default void handleWithRuntimeException(EVENT e) {
          try {
            handle(e);
          }
          catch(Exception exception) {
            throw exception instanceof RuntimeException ? (RuntimeException) exception : new RuntimeException(exception);
          }
        }
      }
    
      public static void main(String[] args) throws Exception {
        // -------------------------------------------------------------------------------------------------------------------------------------
        // demo usage
        // -------------------------------------------------------------------------------------------------------------------------------------
        JToggleButton toggleButton = new JToggleButton();
        JFrame frame = new JFrame();
        JTextField textField = new JTextField();
        JScrollBar scrollBar = new JScrollBar();
        ListSelectionModel listSelectionModel = new DefaultListSelectionModel();
    
        // ActionListener
        toggleButton.addActionListener(ActionPerformed.handle(e -> LOGGER.info(e.toString())));
    
        // ItemListener
        toggleButton.addItemListener(ItemStateChanged.handle(e -> LOGGER.info(e.toString())));
    
        // ChangeListener
        toggleButton.addChangeListener(StateChanged.handle(e -> LOGGER.info(e.toString())));
    
        // MouseListener
        frame.addMouseListener(MouseClicked.handle(e -> LOGGER.info(e.toString())));
        frame.addMouseListener(MousePressed.handle(e -> LOGGER.info(e.toString())));
        frame.addMouseListener(MouseReleased.handle(e -> LOGGER.info(e.toString())));
        frame.addMouseListener(MouseEntered.handle(e -> LOGGER.info(e.toString())));
        frame.addMouseListener(MouseExited.handle(e -> LOGGER.info(e.toString())));
    
        // MouseMotionListener
        frame.addMouseMotionListener(MouseDragged.handle(e -> LOGGER.info(e.toString())));
        frame.addMouseMotionListener(MouseMoved.handle(e -> LOGGER.info(e.toString())));
    
        // MouseWheelListenere
        frame.addMouseWheelListener(MouseWheelMoved.handle(e -> LOGGER.info(e.toString())));
    
        // KeyListener
        frame.addKeyListener(KeyTyped.handle(e -> LOGGER.info(e.toString())));
        frame.addKeyListener(KeyPressed.handle(e -> LOGGER.info(e.toString())));
        frame.addKeyListener(KeyReleased.handle(e -> LOGGER.info(e.toString())));
    
        // FocusListener
        frame.addFocusListener(FocusGained.handle(e -> LOGGER.info(e.toString())));
        frame.addFocusListener(FocusLost.handle(e -> LOGGER.info(e.toString())));
    
        // ComponentListener
        frame.addComponentListener(ComponentMoved.handle(e -> LOGGER.info(e.toString())));
        frame.addComponentListener(ComponentResized.handle(e -> LOGGER.info(e.toString())));
        frame.addComponentListener(ComponentShown.handle(e -> LOGGER.info(e.toString())));
        frame.addComponentListener(ComponentHidden.handle(e -> LOGGER.info(e.toString())));
    
        // ContainerListener
        frame.addContainerListener(ComponentAdded.handle(e -> LOGGER.info(e.toString())));
        frame.addContainerListener(ComponentRemoved.handle(e -> LOGGER.info(e.toString())));
    
        // HierarchyListener
        frame.addHierarchyListener(HierarchyChanged.handle(e -> LOGGER.info(e.toString())));
    
        // PropertyChangeListener
        frame.addPropertyChangeListener(PropertyChange.handle(e -> LOGGER.info(e.toString())));
        frame.addPropertyChangeListener("propertyName", PropertyChange.handle(e -> LOGGER.info(e.toString())));
    
        // WindowListener
        frame.addWindowListener(WindowOpened.handle(e -> LOGGER.info(e.toString())));
        frame.addWindowListener(WindowClosing.handle(e -> LOGGER.info(e.toString())));
        frame.addWindowListener(WindowClosed.handle(e -> LOGGER.info(e.toString())));
        frame.addWindowListener(WindowIconified.handle(e -> LOGGER.info(e.toString())));
        frame.addWindowListener(WindowDeiconified.handle(e -> LOGGER.info(e.toString())));
        frame.addWindowListener(WindowActivated.handle(e -> LOGGER.info(e.toString())));
        frame.addWindowListener(WindowDeactivated.handle(e -> LOGGER.info(e.toString())));
    
        // WindowStateListener
        frame.addWindowStateListener(WindowStateChanged.handle(e -> LOGGER.info(e.toString())));
    
        // DocumentListener
        textField.getDocument().addDocumentListener(InsertUpdate.handle(e -> LOGGER.info(e.toString())));
        textField.getDocument().addDocumentListener(RemoveUpdate.handle(e -> LOGGER.info(e.toString())));
        textField.getDocument().addDocumentListener(InsertOrRemoveUpdate.handle(e -> LOGGER.info(e.toString())));
        textField.getDocument().addDocumentListener(ChangedUpdate.handle(e -> LOGGER.info(e.toString())));
    
        // AdjustmentListener
        scrollBar.addAdjustmentListener(AdjustmentValueChanged.handle(e -> LOGGER.info(e.toString())));
    
        // ListSelectionListener
        listSelectionModel.addListSelectionListener(ValueChanged.handle(e -> LOGGER.info(e.toString())));
    
        // ...
        // enhance as needed
      }
    
      // @formatter:off
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // ActionListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class ActionPerformed implements ActionListener {
        private AdapterEventHandler<ActionEvent> m_handler = null;
        public static ActionPerformed handle(AdapterEventHandler<ActionEvent> handler) { ActionPerformed adapter = new ActionPerformed(); adapter.m_handler = handler; return adapter; }
        @Override public void actionPerformed(ActionEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // ItemListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class ItemStateChanged implements ItemListener {
        private AdapterEventHandler<ItemEvent> m_handler = null;
        public static ItemStateChanged handle(AdapterEventHandler<ItemEvent> handler) { ItemStateChanged adapter = new ItemStateChanged(); adapter.m_handler = handler; return adapter; }
        @Override public void itemStateChanged(ItemEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // ChangeListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class StateChanged implements ChangeListener {
        private AdapterEventHandler<ChangeEvent> m_handler = null;
        public static StateChanged handle(AdapterEventHandler<ChangeEvent> handler) { StateChanged adapter = new StateChanged(); adapter.m_handler = handler; return adapter; }
        @Override public void stateChanged(ChangeEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // MouseListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class MouseClicked extends MouseAdapter {
        private AdapterEventHandler<MouseEvent> m_handler = null;
        public static MouseClicked handle(AdapterEventHandler<MouseEvent> handler) { MouseClicked adapter = new MouseClicked(); adapter.m_handler = handler; return adapter; }
        @Override public void mouseClicked(MouseEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class MousePressed extends MouseAdapter {
        private AdapterEventHandler<MouseEvent> m_handler = null;
        public static MousePressed handle(AdapterEventHandler<MouseEvent> handler) { MousePressed adapter = new MousePressed(); adapter.m_handler = handler; return adapter; }
        @Override public void mousePressed(MouseEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class MouseReleased extends MouseAdapter {
        private AdapterEventHandler<MouseEvent> m_handler = null;
        public static MouseReleased handle(AdapterEventHandler<MouseEvent> handler) { MouseReleased adapter = new MouseReleased(); adapter.m_handler = handler; return adapter; }
        @Override public void mouseReleased(MouseEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class MouseEntered extends MouseAdapter {
        private AdapterEventHandler<MouseEvent> m_handler = null;
        public static MouseEntered handle(AdapterEventHandler<MouseEvent> handler) { MouseEntered adapter = new MouseEntered(); adapter.m_handler = handler; return adapter; }
        @Override public void mouseEntered(MouseEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class MouseExited extends MouseAdapter {
        private AdapterEventHandler<MouseEvent> m_handler = null;
        public static MouseExited handle(AdapterEventHandler<MouseEvent> handler) { MouseExited adapter = new MouseExited(); adapter.m_handler = handler; return adapter; }
        @Override public void mouseExited(MouseEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // MouseMotionListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class MouseDragged extends MouseAdapter {
        private AdapterEventHandler<MouseEvent> m_handler = null;
        public static MouseDragged handle(AdapterEventHandler<MouseEvent> handler) { MouseDragged adapter = new MouseDragged(); adapter.m_handler = handler; return adapter; }
        @Override public void mouseDragged(MouseEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class MouseMoved extends MouseAdapter {
        private AdapterEventHandler<MouseEvent> m_handler = null;
        public static MouseMoved handle(AdapterEventHandler<MouseEvent> handler) { MouseMoved adapter = new MouseMoved(); adapter.m_handler = handler; return adapter; }
        @Override public void mouseMoved(MouseEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // MouseWheelListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class MouseWheelMoved extends MouseAdapter {
        private AdapterEventHandler<MouseWheelEvent> m_handler = null;
        public static MouseWheelMoved handle(AdapterEventHandler<MouseWheelEvent> handler) { MouseWheelMoved adapter = new MouseWheelMoved(); adapter.m_handler = handler; return adapter; }
        @Override public void mouseWheelMoved(MouseWheelEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // KeyListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class KeyTyped extends KeyAdapter {
        private AdapterEventHandler<KeyEvent> m_handler = null;
        public static KeyTyped handle(AdapterEventHandler<KeyEvent> handler) { KeyTyped adapter = new KeyTyped(); adapter.m_handler = handler; return adapter; }
        @Override public void keyTyped(KeyEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class KeyPressed extends KeyAdapter {
        private AdapterEventHandler<KeyEvent> m_handler = null;
        public static KeyPressed handle(AdapterEventHandler<KeyEvent> handler) { KeyPressed adapter = new KeyPressed(); adapter.m_handler = handler; return adapter; }
        @Override public void keyPressed(KeyEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class KeyReleased extends KeyAdapter {
        private AdapterEventHandler<KeyEvent> m_handler = null;
        public static KeyReleased handle(AdapterEventHandler<KeyEvent> handler) { KeyReleased adapter = new KeyReleased(); adapter.m_handler = handler; return adapter; }
        @Override public void keyReleased(KeyEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // FocusListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class FocusGained extends FocusAdapter {
        private AdapterEventHandler<FocusEvent> m_handler = null;
        public static FocusGained handle(AdapterEventHandler<FocusEvent> handler) { FocusGained adapter = new FocusGained(); adapter.m_handler = handler; return adapter; }
        @Override public void focusGained(FocusEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class FocusLost extends FocusAdapter {
        private AdapterEventHandler<FocusEvent> m_handler = null;
        public static FocusLost handle(AdapterEventHandler<FocusEvent> handler) { FocusLost adapter = new FocusLost(); adapter.m_handler = handler; return adapter; }
        @Override public void focusLost(FocusEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // ComponentListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class ComponentMoved extends ComponentAdapter {
        private AdapterEventHandler<ComponentEvent> m_handler = null;
        public static ComponentMoved handle(AdapterEventHandler<ComponentEvent> handler) { ComponentMoved adapter = new ComponentMoved(); adapter.m_handler = handler; return adapter; }
        @Override public void componentMoved(ComponentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class ComponentResized extends ComponentAdapter {
        private AdapterEventHandler<ComponentEvent> m_handler = null;
        public static ComponentResized handle(AdapterEventHandler<ComponentEvent> handler) { ComponentResized adapter = new ComponentResized(); adapter.m_handler = handler; return adapter; }
        @Override public void componentResized(ComponentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class ComponentShown extends ComponentAdapter {
        private AdapterEventHandler<ComponentEvent> m_handler = null;
        public static ComponentShown handle(AdapterEventHandler<ComponentEvent> handler) { ComponentShown adapter = new ComponentShown(); adapter.m_handler = handler; return adapter; }
        @Override public void componentShown(ComponentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class ComponentHidden extends ComponentAdapter {
        private AdapterEventHandler<ComponentEvent> m_handler = null;
        public static ComponentHidden handle(AdapterEventHandler<ComponentEvent> handler) { ComponentHidden adapter = new ComponentHidden(); adapter.m_handler = handler; return adapter; }
        @Override public void componentHidden(ComponentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // ContainerListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class ComponentAdded extends ContainerAdapter {
        private AdapterEventHandler<ContainerEvent> m_handler = null;
        public static ComponentAdded handle(AdapterEventHandler<ContainerEvent> handler) { ComponentAdded adapter = new ComponentAdded(); adapter.m_handler = handler; return adapter; }
        @Override public void componentAdded(ContainerEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class ComponentRemoved extends ContainerAdapter {
        private AdapterEventHandler<ContainerEvent> m_handler = null;
        public static ComponentRemoved handle(AdapterEventHandler<ContainerEvent> handler) { ComponentRemoved adapter = new ComponentRemoved(); adapter.m_handler = handler; return adapter; }
        @Override public void componentRemoved(ContainerEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // HierarchyListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class HierarchyChanged implements HierarchyListener {
        private AdapterEventHandler<HierarchyEvent> m_handler = null;
        public static HierarchyChanged handle(AdapterEventHandler<HierarchyEvent> handler) { HierarchyChanged adapter = new HierarchyChanged(); adapter.m_handler = handler; return adapter; }
        @Override public void hierarchyChanged(HierarchyEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // PropertyChangeListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class PropertyChange implements PropertyChangeListener {
        private AdapterEventHandler<PropertyChangeEvent> m_handler = null;
        public static PropertyChange handle(AdapterEventHandler<PropertyChangeEvent> handler) { PropertyChange adapter = new PropertyChange(); adapter.m_handler = handler; return adapter; }
        @Override public void propertyChange(PropertyChangeEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // WindowListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class WindowOpened extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowOpened handle(AdapterEventHandler<WindowEvent> handler) { WindowOpened adapter = new WindowOpened(); adapter.m_handler = handler; return adapter; }
        @Override public void windowOpened(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class WindowClosing extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowClosing handle(AdapterEventHandler<WindowEvent> handler) { WindowClosing adapter = new WindowClosing(); adapter.m_handler = handler; return adapter; }
        @Override public void windowClosing(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class WindowClosed extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowClosed handle(AdapterEventHandler<WindowEvent> handler) { WindowClosed adapter = new WindowClosed(); adapter.m_handler = handler; return adapter; }
        @Override public void windowClosed(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class WindowIconified extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowIconified handle(AdapterEventHandler<WindowEvent> handler) { WindowIconified adapter = new WindowIconified(); adapter.m_handler = handler; return adapter; }
        @Override public void windowIconified(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class WindowDeiconified extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowDeiconified handle(AdapterEventHandler<WindowEvent> handler) { WindowDeiconified adapter = new WindowDeiconified(); adapter.m_handler = handler; return adapter; }
        @Override public void windowDeiconified(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class WindowActivated extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowActivated handle(AdapterEventHandler<WindowEvent> handler) { WindowActivated adapter = new WindowActivated(); adapter.m_handler = handler; return adapter; }
        @Override public void windowActivated(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class WindowDeactivated extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowDeactivated handle(AdapterEventHandler<WindowEvent> handler) { WindowDeactivated adapter = new WindowDeactivated(); adapter.m_handler = handler; return adapter; }
        @Override public void windowDeactivated(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // WindowStateListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class WindowStateChanged extends WindowAdapter {
        private AdapterEventHandler<WindowEvent> m_handler = null;
        public static WindowStateChanged handle(AdapterEventHandler<WindowEvent> handler) { WindowStateChanged adapter = new WindowStateChanged(); adapter.m_handler = handler; return adapter; }
        @Override public void windowStateChanged(WindowEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // DocumentListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class DocumentAdapter implements DocumentListener {
        @Override public void insertUpdate(DocumentEvent e) { /* nothing */ }
        @Override public void removeUpdate(DocumentEvent e) { /* nothing */ }
        @Override public void changedUpdate(DocumentEvent e) { /* nothing */ }
      }
    
      public static class InsertUpdate extends DocumentAdapter {
        private AdapterEventHandler<DocumentEvent> m_handler = null;
        public static InsertUpdate handle(AdapterEventHandler<DocumentEvent> handler) { InsertUpdate adapter = new InsertUpdate(); adapter.m_handler = handler; return adapter; }
        @Override public void insertUpdate(DocumentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class RemoveUpdate extends DocumentAdapter {
        private AdapterEventHandler<DocumentEvent> m_handler = null;
        public static RemoveUpdate handle(AdapterEventHandler<DocumentEvent> handler) { RemoveUpdate adapter = new RemoveUpdate(); adapter.m_handler = handler; return adapter; }
        @Override public void removeUpdate(DocumentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class InsertOrRemoveUpdate extends DocumentAdapter {
        private AdapterEventHandler<DocumentEvent> m_handler = null;
        public static InsertOrRemoveUpdate handle(AdapterEventHandler<DocumentEvent> handler) { InsertOrRemoveUpdate adapter = new InsertOrRemoveUpdate(); adapter.m_handler = handler; return adapter; }
        @Override public void insertUpdate(DocumentEvent e) { m_handler.handleWithRuntimeException(e); }
        @Override public void removeUpdate(DocumentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      public static class ChangedUpdate extends DocumentAdapter {
        private AdapterEventHandler<DocumentEvent> m_handler = null;
        public static ChangedUpdate handle(AdapterEventHandler<DocumentEvent> handler) { ChangedUpdate adapter = new ChangedUpdate(); adapter.m_handler = handler; return adapter; }
        @Override public void changedUpdate(DocumentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // AdjustmentListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class AdjustmentValueChanged implements AdjustmentListener {
        private AdapterEventHandler<AdjustmentEvent> m_handler = null;
        public static AdjustmentValueChanged handle(AdapterEventHandler<AdjustmentEvent> handler) { AdjustmentValueChanged adapter = new AdjustmentValueChanged(); adapter.m_handler = handler; return adapter; }
        @Override public void adjustmentValueChanged(AdjustmentEvent e) { m_handler.handleWithRuntimeException(e); }
      }
    
      // ---------------------------------------------------------------------------------------------------------------------------------------
      // ListSelectionListener
      // ---------------------------------------------------------------------------------------------------------------------------------------
      public static class ValueChanged implements ListSelectionListener {
        private AdapterEventHandler<ListSelectionEvent> m_handler = null;
        public static ValueChanged handle(AdapterEventHandler<ListSelectionEvent> handler) { ValueChanged adapter = new ValueChanged(); adapter.m_handler = handler; return adapter; }
        @Override public void valueChanged(ListSelectionEvent e) { m_handler.handleWithRuntimeException(e); }
      }
      // @formatter:on
    }
    

    【讨论】:

      【解决方案6】:

      无法从 lambda 表达式中访问默认方法。以下代码无法编译:

      interface Formula {
          double calculate(int a);
      
          default double sqrt(int a) {
              return Math.sqrt(a);
          }
      }
      Formula formula = (a) -> sqrt( a * 100);
      

      仅适用于功能接口(仅单个抽象方法 + 任意数量的默认方法),因此 lambda 表达式仅适用于抽象方法

      【讨论】:

      • 抱歉,我不明白这与问题有什么关系
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多