0

数週間前にプロジェクトで一般的なリンクされたリストを実装したばかりで、IT WORKS ! ただし、1 つの問題があります。私はキャストを余儀なくされています(そして期待していませんでした)。

ここにいくつかのスニペットがあります。一般的なスタックから始めて、問題を定義するのに十分であることを願っています:

    public class GenericStack<E> {

      public LinkedList <E> stack = new LinkedList<>();

      public void push (E obj){
        stack.add(obj);
      }

      public E pop() {
        if (stack.isEmpty()) return null;
        return stack.removeLast();
      }
      ...
}

ジェネリック スタックを使用するクラス定義は次のとおりです。

public class Grid extends GenericStack<JTextField> implements ActionListener, KeyListener, KeyCodes

これが私の定義stackであり、私がプッシュしてポップしているものです:

  GenericStack stack = new GenericStack();
  public static JTextField[][] cells = new JTextField[11][11];

ここに私が押していますstack

 stack.push(Grid.cells[currentCell.row][currentCell.col]);

ここでは、stack,表示されているキャストを行う場合にのみ、どの作品からポップするかを示します。

  private void calculate(){
    JTextField w = new JTextField();
    while(stack.size()>0){
      w =  (JTextField) stack.pop();
      System.out.println("stack element " + w.getText());
    }
  }

今、私は文句を言っていません。対処する問題があるかどうかさえわかりませ(JTextField)んが、キャストがないと、「INCOMPATIBLE TYPES--REQUIRED: JTextField; FOUND: Object」が表示stack.pop()されますが、ジェネリック型を返すように明確に定義されてJTextFieldいます。キャストする必要がありますか?

4

3 に答える 3

4

これが問題です:

GenericStack stack = new GenericStack();

の生の型を使用していGenericStackます。GenericStack<JTextField>正直なところ、すでに拡張しているのに、なぜこれを取得したのかは明らかではありません。コンポジションを使用することを期待しています:

public class Grid implements ActionListener, KeyListener, KeyCodes {
    private final GenericStack<JTextField> stack = new GenericStack<JTextField>();

    private void calculate() {
        while (stack.size() > 0) {
            JTextField w = stack.pop();
            System.out.println("stack element " + w.getText());
        }
    }
}

または継承を使用します。

public class Grid extends GenericStack<JTextField> 
    implements ActionListener, KeyListener, KeyCodes {

    private void calculate() {
        while (size() > 0) {
            JTextField w = pop();
            System.out.println("stack element " + w.getText());
        }
    }
}

現時点では、2 つをミックスしていますが、これは非常に奇妙です。

于 2013-10-11T21:18:52.630 に答える
1

次のインスタンス化でジェネリック型の raw 型を使用しました:

GenericStack stack = new GenericStack();  

生の型を使用すると、クラス内のすべてのジェネリック型が対応する生の型に置き換えられ、型パラメーターが消去によって置き換えられます。Eあなたの場合の消去はであるためObject、バインドはありません。したがって、リンクされたリストとメソッド:

public LinkedList <E> stack = new LinkedList<>();
public void push (E obj) { ... }
public E pop() { ... }

に消去されます:

public LinkedList stack = new LinkedList();
public void push(Object obj) { ... }
public Object pop() { ... }

したがって、メソッドObjectを呼び出すと、型が返されますpop()

必要なのは、パラメータ化されたインスタンス化です:

GenericStack<JTextField> stack = new GenericStack<>();

そしてもちろん、ジョンスキートが彼の答えで言ったこと。継承と構成を混同しないでください。type の参照がありGenericStack、それを拡張しています。意味がありません。Jon's answer のアドバイスに従ってください。

于 2013-10-11T21:18:42.883 に答える