java - 为什么 ChangeListener 的 getSource() 不返回用于生成事件的类型的预转换对象?

标签 java swing changelistener

为什么 e.getSource() 不简单地返回一个用于生成事件? e.getSource() 的第一次使用清楚地表明它知道正在使用 JSpinner,那么为什么不将其强制转换回来呢?好像这样会简单一些。我假设出于安全原因不这样做,但我想看到或听到一个具体的例子,为什么将其作为默认用法是一件坏事。

不安全吗?这只是糟糕的架构吗?

public class SpinnerPanel extends JPanel implements ChangeListener {

...

SpinnerPanel()
{
    birthdaySpinner.addChangeListener(this);
    add(birthdaySpinner);
}

@Override
public void stateChanged(ChangeEvent e) 
{
    System.out.println(e.getSource());

    JSpinner spinner = (JSpinner)e.getSource();
    System.out.println(spinner.getValue());
}
}

最佳答案

事实上,源将是 JSpinner 在运行时是已知的。您所描述的那种“自动类型转换”可以在编译时使用泛型来实现,但那时不知道监听器可能会在哪里结束。例如,您可以使用微调器,获取所有监听器的列表,然后将这些监听器添加到另一个小部件(例如复选框)。您的代码中没有任何内容可以在编译时告诉编译器这种情况不会发生,因此没有任何内容可以告诉编译器源将始终是旋转器。

理论上,可以通过某种方式使用泛型。你可以有一个 ChangeEvent<T>对于源自类 T 的组件的更改。你可以有一个 ChangeListener<T>使用方法stateChanged(ChangeEvent<? extends T>) 。但是类 T 的给定组件的所有监听器的类型是什么? ?如果是List<ChangeEvent<T>>那么您将不被允许添加通用 ChangeListener<Object>到那个 list 。所以它必须是 List<ChangeEvent<? super T>> 。但是,如果您在任何组件中都有这样的列表,那么对于所有派生组件来说,它将是相同的类型,而不是像泛型方法所建议的更具体的类型。

所以总的来说,我认为这种泛型方法会使代码更难编写和维护,可能会在某些地方留下漏洞,在向后兼容性方面可能会很糟糕,而且总的来说不值得努力。

关于java - 为什么 ChangeListener 的 getSource() 不返回用于生成事件的类型的预转换对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17846838/

相关文章:

java - Primefaces p :poll tag

java - 为什么在为我的玩家分配名称时会出现空指针异常?

java - 在 JPanel 中生成包含多个点的图

java - 一个对象中的图形正在影响另一个对象的图形 - JAVA

java - 覆盖按钮背景

java - JTabbedPane触发事件

java - JTabbedPane ChangeListener

java - 中断正在运行 Stream API 操作的线程

java - 为什么 JTabbedPane 的 ChangeListener 会随着主 JFrame 的启动而加载?

java - Java 中是否存在与带有引用变量的 for-each 循环等效的方法?