1

getValue() メソッドにアクセスできるように ChangeEvent オブジェクトを JSpinner オブジェクトにキャストし直す代わりに、なぜ 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

ソースが になるという事実は、JSpinner実行に認識されます。あなたが説明した種類の「自動型キャスト」は、コンパイル時にジェネリックで可能ですが、その時点では、リスナーがどこに行き着くかはわかりません。たとえば、スピナーを使用してすべてのリスナーのリストを取得し、これらのリスナーをチェック ボックスなどの別のウィジェットに追加できます。コードには、コンパイル時にこれが起こらないことをコンパイラに伝えるものは何もないため、ソースが常にスピナーになることをコンパイラに伝えるものは何もありません。

理論的には、何らかの方法でジェネリックを使用することは可能です。ChangeEvent<T>class のコンポーネントに起因する変更を行うことができますTChangeListener<T>method を持つことができますstateChanged(ChangeEvent<? extends T>)。しかし、その場合、 class の特定のコンポーネントのすべてのリスナーの型は何でしょうTか? そうであれば、そのリストList<ChangeEvent<T>>にジェネリックを追加することはできません。ChangeListener<Object>だからそれはする必要がありますList<ChangeEvent<? super T>>。ただし、コンポーネントにそのようなリストがある場合、ジェネリックアプローチが示唆するようなより具体的なタイプではなく、すべての派生コンポーネントで同じタイプになります。

したがって、全体として、このジェネリックアプローチはコードの記述と保守を非常に困難にし、いくつかの場所に抜け穴を残す可能性が高く、後方互換性の点でおそらく恐ろしいものであり、全体として努力する価値はないと思います.

于 2013-07-25T08:10:38.730 に答える