Error in generic code

I am getting this error "Type mismatch: cannot convert from Object to E" in the last line of the pop() method.

Node

public class Node<E> {  
    E item;
    Node next;

    Node(E item) {
        this.item = item;
        this.next = null;
    }

    Node(E item, Node next) {
        this.item = item;
        this.next = next;
    }
}

Stack

import java.util.NoSuchElementException;

public class Stack<E> {
    private Node head;
    private int size;

    Stack() {
        head = null;
        size = 0;
    }

    public void push(E item) {
        head = new Node (item, head);
        size++;
    }

    public E pop() throws NoSuchElementException {
        Node nodeToBePopped;
        if (size == 0) {
            throw new NoSuchElementException();
        }
        nodeToBePopped = head;
        head = head.next;
        size--;
        return nodeToBePopped.item;
    }
}

I don't understand why that error occurs despite item being declared as type E in the Node class. Why do I have to make an explicit cast in this instance?

Jon Skeet
people
quotationmark

This is the problem in Stack<E>:

private Node head;

and likewise later:

Node nodeToBePopped;

And in Node<E> itself:

Node next;

You're using the raw type Node here, so all the generics are lost, effectively. See the Java Generics FAQ for more information about raw types.

Just change the variable types to Node<E> and it should be fine.

I'd also recommend using private fields, and only declaring local variables at the point of first use - so your pop method would become:

public E pop() throws NoSuchElementException {
    if (size == 0) {
        throw new NoSuchElementException();
    }
    Node<E> nodeToBePopped = head;
    head = head.next;
    size--;
    return nodeToBePopped.item;
}

Or in fact, just find the value to return from head before you change what head refers to:

public E pop() throws NoSuchElementException {
    if (size == 0) {
        throw new NoSuchElementException();
    }
    E previousHeadValue = head.item;
    head = head.next;
    size--;
    return previousHeadValue;
}

people

See more on this question at Stackoverflow