views:

171

answers:

5

Kushal Paudyal asked how deep you can nest inner classes in Java. The consensus is that while the language itself imposes no limit, the underlying OS and file system may.

Have you ever found a case where two or more levels of nested inner classes are helpful?

Update (11/28): If you consider enum classes, a second level of nesting can make sense. During some recent refactoring, I briefly had an outer class (an HTTP client), an inner class (an in-memory cache), and inside the inner class an enum class (for the cache eviction strategies). This seemed okay, but to @Thorbjørn's point, I continued by extracting the cache class and its inner enum up out of the HTTP client class.

+3  A: 

I have not personally run into a case where more than one proved necessary. I could forsee a case where two may prove useful. I have trouble imagining more than two however.

The example I'm imagining is in Java GUI code. It may be useful in certain circumstances to have a class nested inside an already nested ActionListener.

Daniel Bingham
+3  A: 

No. I have not.

The standard example of a class inside a class is the Builder, where you have a subclass to help create a proper instance given a lot of possible configuration methods.

Personally I would consider a more complex case of nested classes an excellent example of code which needs refactoring.

Thorbjørn Ravn Andersen
I tend to agree.
Jim Ferrans
Please note, I do not consider anonymous classes in this. They are a necessary pain if you need "easy" access to outside variables. I would however strongly consider an anonymous class inside another to be a code smell.
Thorbjørn Ravn Andersen
+1  A: 

Sure - this is valid sometimes. I just did some a few minutes ago.

For example, in some test code I wrote, I wanted to set up some boilerplate that handled running multiple callables. The boilerplate needed to create multiple instances of a callable chunk of code. In this example, I'm creating an instance of a factory to pass into threadedTest, and that factory creates new callables.

@Test public void testXXXXXXXX() throws Throwable {
    threadedTest(new CallableFactory() {
        @Override public Callable<Request> create() {
            return new Callable<Request>() {
                // might have state
                @Override public Request call() throws Exception {
                    // do the steps for this test
                    return ...;
                }};
        }});
}

Much more concise than creating two new classes where one just creates the other. Of course there's a readability penalty here until you're used to the style, though...

If you combined this with a template method to control transactions or database connect/close, this could end up three deep. (I've had some code like that; if you do it, make sure you write a dummy sample in your comments and explain the structure well)

Scott Stanchfield
Those are anonymous inner classes, not nested inner classes. The two concepts are treated differently at http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
Thorbjørn Ravn Andersen
The above could easily have been nested classes, though I wouldn't want to write it that way ;)
Scott Stanchfield
+1  A: 

If you're generating code from some data, nested classes can be a good way of avoiding name collisions.

Jimmy
+1  A: 

I saw usage of number of levels of nested classes.

There is a legacy machine named Tandem (of HP), that originally runs code of COBOL/C. There are later "patches" that enable that machine of running java too. The variables structure of COBOL are naturally multi-leveled (even 5 levels is a common case), so in order to allow java to call to COBOL servers the java classes were also multi-leveled in order to simplify the conversion of the data between them.

I agree that this is a very uncommon case, but anyway...

jutky