2

I'm trying to figure out subtle difference in implementation of static nested class vs inner class (non-static nested class). For example, on http://algs4.cs.princeton.edu/code/edu/princeton/cs/algs4/Queue.java.html, you can find the following code:

public class Queue<Item> implements Iterable<Item> {
    private Node<Item> first;    // beginning of queue
    private Node<Item> last;     // end of queue
    private int N;               // number of elements on queue

    // helper linked list class
    private static class Node<Item> {
        private Item item;
        private Node<Item> next;
    }

    ...
    /**
     * Returns an iterator that iterates over the items in this queue in FIFO order.
     *
     * @return an iterator that iterates over the items in this queue in FIFO order
     */
    public Iterator<Item> iterator()  {
        return new ListIterator<Item>(first);  //why parameter needed?
    }

    // an iterator, doesn't implement remove() since it's optional
    private class ListIterator<Item> implements Iterator<Item> {
        private Node<Item> current;  //why not current = first?

        public ListIterator(Node<Item> first) {
            current = first;
        }

        public boolean hasNext()  { return current != null;                     }
        public void remove()      { throw new UnsupportedOperationException();  }

        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = current.item;
            current = current.next; 
            return item;
        }
    }
    ...

I wonder why you have to pass the variable first via the constructor of ListIterator? Why can't I just use private Node<Item> current = first; at declaration. I know that if I have used inner class for Node, I can directly assign first to current (like in http://algs4.cs.princeton.edu/13stacks/LinkedQueue.java.html).

2
  • 1
    it's not needed, but it's better encapsulation. Commented Feb 4, 2016 at 23:33
  • 1
    Congratulations on getting the terminology correct. Commented Feb 5, 2016 at 0:23

1 Answer 1

1

Nested classes are a little weird. In this first example, we have a static nested class. It has to access variable via a "parent" instance of OuterClass because it has no enclosing OuterClass instance. When we define nested classes statically, it's almost as if they were defined in their own separate file. The only difference is that static nested classes get access to private members of OuterClass whereas they wouldn't if they were defined in their own separate file.

public class OuterClass{
    private Object variable = "variable";

    private static class StaticNestedClass{
        private OuterClass parent;

        private StaticNestedClass(OuterClass p){ parent = p; }

        private void method(){
            //This line compiles:
            System.out.println("variable = "+parent.variable);

            //This won't - there's no OuterClass enclosing instance:
            //System.out.println("variable = "+OuterClass.this.variable);

            //This one won't either, for the same reason:
            //System.out.println("variable = "+variable);
        }
    }
}

Let's change it up a bit. Now our nested class is NOT static, meaning it comes enclosed in an instance of OuterClass. It still gets access to private members of OuterClass, but we don't need to store an instance of OuterClass to its constructor for storage purposes because it implicitly has a reference to the OuterClass instance that encloses it.

public class OuterClass{
    private Object variable = "variable";

    private class InnerClass{
        private void method(){
            //This line compiles:
            System.out.println("variable = "+variable);

            //So does this one - both lines refer to the same 
            //enclosing instance of OuterClass:
            System.out.println("variable = "+OuterClass.this.variable);
        }
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

'Static inner' is a contradiction in terms. OP has this quite correct. Don't confuse the issue.
It's still defined inside of the outer class block, is it not?
Read the link, or the OP's parenthesis. The word you're looking for is 'nested'.
Fixed it - gosh ... I've been using messed up terminology since undergrad 12 years ago ... whoops .... ;)
You're far from alone in that. I've had to post that comment dozens if not hundreds of times here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.