5

I have a question about use of static inner class in the following code, adapted from Eckel's Thinking in Java 4th edition (page 625).

The code uses a static inner class called Node. When you create a Stack structure, you can then push the nodes onto the stack and pop them off - so far so good. But I'm confused about why the node class is static? Wouldn't that mean that there would be only one Node created in the LinkedStack class? How / why is it that in fact you can push many different nodes onto the stack, and then pop them off (which of course is what the stack is supposed to do). In fact, you can change private static class Node to 'private class Node` and it also works ... so why did Eckels choose static class Node?

In this example, the input is the three words "Phasers", "on", "stun!" and output is "stun!", "on", "Phasers".

public class LinkedStack<T> {

    //generic inner class node
    private static class Node<U> {

        U item;
        Node<U> next;
        Node() {
            item = null;
            next = null;
        }
        Node(U item, Node<U> next) {
            this.item = item;
            this.next = next;
        }
        boolean isDummyNode() {
            return item == null && next == null;
        }
    }

    //initialize top of stack as a dummy first node
    private Node<T> top = new Node<T>();

    public void push(T item) {
        top = new Node<T>(item, top);
    }

    public T pop() {
        T result = top.item;
        if(!top.isDummyNode())
            top = top.next;
        return result;
    }

    public static void main(String[] args) {
        LinkedStack<String> stack = new LinkedStack<String>();
        for(String s : "Phasers on stun!".split(" "))
            stack.push(s);
        String s;
        while((s = stack.pop()) != null)
            System.out.println(s);
    }

}
topsail
  • 2,186
  • 3
  • 17
  • 17
  • Other question doesn't have an answer to mine. Plus I'm obviously reading and researching since the questions comes from Eckel's book about Java. Can I appeal your decision? – topsail Dec 17 '14 at 21:00
  • *I'm confused about why the node class is static?* This is explained in the duplicate Q/A. *Wouldn't that mean that there would be only one Node created in the LinkedStack class?* It's a class, and you can create many instances of a class, despite if it's top class or inner class (this is not rocket science). *How / why is it that in fact you can push many different nodes onto the stack...* they are instances, and you can make them behave as you desire. With all this, your question boils down to *why the node class is static?* which can be answered by reading the dup. – Luiggi Mendoza Dec 17 '14 at 21:09
  • @topsail: on appealing, any user with a gold badge in java can reopen this. or editing the question will send this to the reopen review queue. but i think Luiggi's linked answer should address your question, if only you can let go of your incorrect understanding of the keyword `static`. – Nathan Hughes Dec 17 '14 at 21:27
  • I've just read it again :) What I find weird is that static classes are supposed to not be able to have many instances. Isn't that the point? You say you can have many instances of a class, but we can't create many Math objects, right? I'm asking for clarification so I can understand this. You guys are helping me a lot and it will really help me to have an expert who can point exactly to what I am missing. – topsail Dec 17 '14 at 21:28
  • @topsail: no, it's not the point. static just means there is no reference to an object of the parent class. – Nathan Hughes Dec 17 '14 at 21:28
  • 2
    @topsail you're confusing `static class` with `static` members (field or method) of the class. A `static` class is like a top class but declared inside a class. Why to do this? Well, imagine you just don't want clients of your `LinkedStack` class could create a `Node` arbitrarily and play with them, so declaring a `public class` is not a good idea, and declaring it as a simple `class` (default package) still makes it accessible for classes in the same package, so instead you declare it as a `private static class` inside `LinkedStack` to limit the usage of `Node` to `LinkedStack` only. – Luiggi Mendoza Dec 17 '14 at 21:32
  • In my app programming never had the need to make a static inner class. prefer to make a top level class. my advise move on to more useful topics in ur study like TDD, web apps, see ...http://codingbat.com – tgkprog Dec 17 '14 at 21:33
  • 1
    @tgkprog this is a great example to understand the benefits of defining `private static class`es, just check my comment above yours. – Luiggi Mendoza Dec 17 '14 at 21:34
  • Okay. You guys have helped. I'm still working at learning this. I've spent the last two weeks studying Java five hours a day with Eckels book. It just helps to be able to ask a question directly about things I don't understand. All students - even the hard working ones have questions to ask. So that's why I came here. You guys are the best around. In this case, I think Eckel's wanted the nested class to have access to the push and pop methods (maybe just for ease of writing the example which is about generics, not nested classes). But probably it's not really the best design (?). – topsail Dec 17 '14 at 21:39
  • yep heard that before. i guess i never felt my clients will do something they are not supposed to. mostly cause its app code. not open src libraries. and with reflection can't u change access at run time anyway? – tgkprog Dec 17 '14 at 21:40
  • For me, it's a good design. As long as you only provide to your clients the necessary elements, there's nothing wrong about it. Note that clients of `LinkedStack` won't ever interact with `Node` directly. There are cases where you would just want to declare this `static class` or `static interface` as `public` like [`Map.Entry`](http://docs.oracle.com/javase/8/docs/api/java/util/Map.Entry.html). – Luiggi Mendoza Dec 17 '14 at 21:41
  • @tgkprog yes you can do it with reflection unless you use a `SecurityManager` and avoid any reflection-harmful changes on your instances at runtime. – Luiggi Mendoza Dec 17 '14 at 21:42
  • One thing I didn't realize - you actually *cannot* create static outer classes. So Math wouldn't be a static class, just a class with static methods. Starting to understand now! This page had some good extra info (probably more or less what Luiggi was trying to get me to understand at the StackOverflow page); ttp://www.geeksforgeeks.org/static-class-in-java/ – topsail Dec 17 '14 at 21:53
  • Just to note, that question has 16 answers, do not read the accepted one only. – Luiggi Mendoza Dec 17 '14 at 21:57

2 Answers2

3

No, Static inner classes are classes which dont require an instance of the enclosing type, it is not the same thing as Static when used in the context of a method or field. Static for an inner class essentailly makes them a top level class. When you declare a non static inner class it has implicit access to the instance fields and methods of the enclosing type, thus making an instance of said type a requirement. Static classes dont have that luxury, and therefore dont require an instance of the enclosing type.

Mark W
  • 2,791
  • 1
  • 21
  • 44
  • 1
    But we clearly can't use a LinkedStack without instantiation? So isn't it pointless (or otherwise meaningless) to have static nodes here? – topsail Dec 17 '14 at 20:58
  • So `static class Node` when nested in LinkedStack means you can have lots of Node objects? But `static class Node` when not nested in LinkedStack would mean there is only one node? – topsail Dec 17 '14 at 21:24
0

A static inner class is associated with the outer class (in this case LinkedStack) and not to an instance of it. For non-static inner classes, there should be an enclosing instance of the outer class. If Node were not static, it means that for any instance of Node to exist, there must be an instance of LinkedStack that encloses that instance.

Having the Node class as static makes it more of a top-level class that is not bound to an instance of the outer class. Hence other classes can create instances of Node without creating any instance of LinkedStack.

See Nested classes from the Java tutorials for more details on the differences.

M A
  • 71,713
  • 13
  • 134
  • 174
  • Okay, your answer is very similar to that of Mark W. My thinking is that Eckel's code is not good in the sense that wouldn't want to have Nodes defined for this class and then open them up to any kind of use anywhere else. Maybe he just did it because it was easier for a textbook example? If Nodes are meant to be as things you can make outside of LinkedStack, it seems odd to make them inner classes of LinkedStack. That's my thinking so far anyway. – topsail Dec 17 '14 at 21:14
  • @topsail The `Node` class is not even an inner class in the first place. An inner class is by definition a non-static nested class. You can think of `LinkedStack` as providing a namespace for `Node`. It is simply a top-level class that is nested inside `LinkedStack`. – M A Dec 17 '14 at 21:24
  • Thanks. My final conclusion (not necessarily correct) is that there is no particular reason here for a static nested class. It's private anyway, so a Node can't be created outside of a LinkedStack class. Therefore a nested static class does nothing that a (non-static) inner class also does. Plus a (non-static) inner class can access the generic type parameter (T) of the outer class and you don't need the extra generic-fication that the static nested class must use. – topsail Dec 18 '14 at 19:05