CodeQL 文档

事件适配器的错误实现

ID: java/wrong-swing-event-adapter-signature
Kind: problem
Security severity: 
Severity: warning
Precision: medium
Tags:
   - reliability
   - maintainability
   - frameworks/swing
Query suites:
   - java-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

Swing(和抽象窗口工具包)中的事件适配器为程序员实现事件侦听器提供了一种便捷的方式。但是,必须注意正确获取重写方法的名称,否则不会调用事件处理程序。

深入了解

Swing(和抽象窗口工具包)中的事件侦听器接口有许多方法。例如,java.awt.event.MouseListener 定义如下

public interface MouseListener extends EventListener {
    public abstract void mouseClicked(MouseEvent);
    public abstract void mousePressed(MouseEvent);
    public abstract void mouseReleased(MouseEvent);
    public abstract void mouseEntered(MouseEvent);
    public abstract void mouseExited(MouseEvent);
}

大量的方法可能使此类接口冗长且乏味,尤其是因为很少需要重写所有方法。更常见的是,您只需要重写一个方法,例如 mouseClicked 事件。

出于此原因,Swing 提供了适配器类,该类提供接口方法的默认空白实现。一个示例是 MouseAdapter,它为 MouseListenerMouseWheelListenerMouseMotionListener 中的方法提供默认实现。(请注意,适配器通常实现多个接口以避免大量的小适配器类。)这使得程序员可以轻松地仅实现他们从给定接口需要的那些方法。

不幸的是,适配器类也是潜在缺陷的来源。由于 @Override 注释不是强制性的,因此程序员很容易不使用它,然后键入错误的方法名称。这会引入一个新方法,而不是实现相关的事件处理程序。

建议

确保任何重写方法与重写方法具有完全相同的名称。

示例

在以下示例中,程序员尝试实现 mouseClicked 函数,但拼写错误。这使得函数无法操作,但程序员没有收到编译器的任何警告。

add(new MouseAdapter() {
    public void mouseClickd(MouseEvent e) {
        // ...
    }
});

在以下修改后的示例中,函数名称拼写正确。它还紧随 @Override 注释,如果不存在要重写具有相同名称的函数,该注释将导致编译器显示错误。

add(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        // ...
    }
});

参考

  • D. Flanagan,Java Foundation Classes in a Nutshell,第 26 章。O’Reilly,1999 年。

  • Java API 规范:注释类型覆盖

  • Java 教程:事件适配器

  • ©GitHub, Inc.
  • 条款
  • 隐私