Parzival
Parzival

Reputation: 623

Explain this Generics Behavior in JAVA

public class MyList<Item> implements Iterable<Item> {
    Node<Item> first;
    int n = 0;

    private static class Node<Item>
    {
        private Item item;
        private Node<Item> next;
    }
    public Iterator<Item> iterator()  {
        return new ListIterator<Item>();
    }

    private class ListIterator<Item> implements Iterator<Item>  // parameter Item is hiding the type Item
    {
        private Node<Item> current = first;  // This does not compile

        public boolean hasNext() {
            return (current != null);   
        }

        public Item next() {
            Item item = current.item;
            current = current.next;
            return current.item;
        }       
    }
    ...
}

The error I get is

"Type Mismatch : can't convert from MyList.Node to MyList.Node".

Not sure if this is related to the warning

"paramter Item is hiding the type item"

If I get a warning for private class ListIterator<Item> implements Iterator<Item>, why did I not get a warning for public class MyList<Item> implements Iterable<Item> ?

Upvotes: 3

Views: 68

Answers (2)

Michael
Michael

Reputation: 44150

The warning very much is related. Your generic type parameter in your inner class hides the generic type parameter in the outer class. So Item in each scope is not the same, hence the two different Node<Item>s are actually different types.

See also: Troubleshooting "The type parameter T is hiding the type T" warning

Eran's answer shows how to fix it, so I won't repeat it.

Upvotes: 3

Eran
Eran

Reputation: 393841

If the generic type parameter of the inner class ListIterator should be the same as the type parameter of the enclosing class MyList, you shouldn't declare it twice.

Change the inner class to:

private class ListIterator implements Iterator<Item>

This way, the type of first and current will be the same.

As Michael commented, you'll have to change the construction of the ListIterator instance to:

public Iterator<Item> iterator()  {
    return new ListIterator();
}

Upvotes: 5

Related Questions