Using generic linked list but forced to use (cast) when popping

I am deliriously overjoyed to say that I just implemented a generic linked list from a few weeks ago in a project and IT WORKS! One problem, though. I am forced to do a cast (and didn't expect to).

Here are some snippets, I hope enough to define problem, starting with the generic stack:

    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();
      }
      ...
}

Here's the class defintion in which I use the generic stack:

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

Here's me defining stack and what I'm pushing and popping:

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

Here's me pushing onto stack:

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

Here's where I pop from stack, which works ONLY IF I DO THE CAST shown:

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

Now I'm not complaining; I'm not even sure there's a problem to deal with, but without the cast (JTextField), I get "INCOMPATIBLE TYPES--REQUIRED: JTextField; FOUND: Object" but stack.pop() is clearly defined to return the generic type, which is JTextField, so why do I need to cast?

Jon Skeet
people
quotationmark

This is the problem:

GenericStack stack = new GenericStack();

That's using the raw type of GenericStack. It's not clear why you've got this at all when you've already extended GenericStack<JTextField> to be honest. I'd expect you to either use composition:

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());
        }
    }
}

or use inheritance:

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());
        }
    }
}

At the moment you're mixing the two, which is really odd.

people

See more on this question at Stackoverflow