bcr
bcr

Reputation: 1328

Inner Class with parameter of Outer Class Type

I would like to create an inner class parametrized on the type of the outer class.

I should say first that I realize there may be a better way to achieve something like my desired result, and I am open to suggestions there, but I'll describe the situation as it stands:

I have a class Node<T> and an attempt at an inner class declaration as below:

public class Node<T> {
    ...

    class NodeIterator<Node<T>> implements Iterator {
        ...
    }
}

This causes a syntax error during compilation, and I infer that this is due to the my use of the outer class, although I do not know this for sure.

Thanks!

Upvotes: 0

Views: 1868

Answers (2)

Paul Bellora
Paul Bellora

Reputation: 55223

Simply do:

public class Node<T> {
    ...

    class NodeIterator implements Iterator<Node<T>> {
        ...
    }
}

As an inner class, an instance of NodeIterator has an implicit reference to an outer Node instance. For this reason, the type T is still in scope within its body.

Note that an alternative would be to make NodeIterator static, losing the implicit outer reference:

static class NodeIterator<T> implements Iterator<Node<T>> {
    ...
}

Here, T must be declared anew, and is different from the T declared by the outer class.

See the Java Tutorials article on nested classes for more info.

Upvotes: 6

Kevin Bowersox
Kevin Bowersox

Reputation: 94469

Specify the generic type argument on the Iterator interface instead of the inner class.

import java.util.Iterator;

public class Node<T> {


    class NodeIterator implements Iterator<Node<T>> {

        @Override
        public boolean hasNext() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public Node<T> next() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void remove() {
            // TODO Auto-generated method stub

        }    
    }
}

I suspect the language does not allow this because nothing would stop you from instantiating a concrete type that does not match the outer classes type such as:

//calling code
Node<Integer> node = new Node<Integer>();

//Node.java
public class Node<T>{

    NodeIterator<String> nodeIterator = new NodeIterator<String>();
}

Upvotes: 1

Related Questions