1

不必将 ChangeEvent 对象转换回 JSpinner 对象以便我可以访问 getValue() 方法,为什么 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());
}
}
4

1 回答 1

2

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

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

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

于 2013-07-25T08:10:38.730 回答