views:

424

answers:

10

In some of my projects and in some books was said to not use inner class (anonymous or not, static or not) - except in some restricted conditions, like EventListeners or Runnables - is a best practice. They even were 'forbiden' in my first industry project.

Is this really a best practice? Why?

(I have to said I use them a lot...)

-- EDIT ---
I can't pick a right answer in all these responses: there's part of rightness on mostly all of them: I'll still use inner classes, but I'll try to use them less often !

+5  A: 

Cleanliness. It's easier to comprehend code if it's broken into logical pieces, not all mushed into the same file.

That said, I do not consider the judicious use of inner classes to be inappropriate. Sometimes these inner classes only exist for one purpose, so I would then have no problem with their being in the only file in which they are used. However, this does not happen that much in my experience.

Michael Myers
In my experience, as soon as you make an inner-class, you need it somewhere else anyway :)
Dolph
It's easier to comprehend code if it's broken into logical pieces, yes -- but in *my* book, that means it's best to define something as close as possible to where it's used, instead of arbitrarily splitting it into a file of its own. ;)
Porculus
inner classes don't exclude you from using them outside the class they live in. Enums are a good example, Enums usually are used for a single class, make it a public static and then you have a context of where that Enum is expected to be used. Factory patterns are a good place for inner classes for producing the implementations without polluting the package namespace with things that should only be instantiated in certain cases controlled by the Factory object.
fuzzy lollipop
Agree but -1 for answering a dupe. You should know better.
finnw
@finnw - there's no need to be a "dupe vigilante" - http://meta.stackoverflow.com/questions/3828/dis-incentive-to-ask-questions-that-will-get-closed - reputation gained from closed/deleted questions go away after a "rep recalc" anyway (though those don't seem to be common).
Nate
@Nate: *Positive* reputation from deleted questions goes away, but finnw's downvote will stay. @finnw: I didn't know it was a dupe. Apparently, neither did any of the other high-rep users who were here (Uri, BalusC, Thorbjørn Ravn Andersen, and Finglas); you're the first to vote to close. And I'm not even sure I agree that http://stackoverflow.com/questions/1028850/are-inner-classes-commonly-used-in-java-are-they-bad is an exact duplicate.
Michael Myers
+5  A: 

Anonymous classes are good to use when doing event based programming especially in swing.

fastcodejava
Why in event based programming and not for other usages, like structures used to regroup numerous parameters, ...This is more a dogma than an explanation: -1.
Guillaume
+1  A: 

Inner classes are appropriate when trying to emulate multiple inheritance. It is similar to what happens under the hood with C++: when you have multiple inheritance in C++, the object layout in memory is actually a concatenation of several object instances; the compiler then works out how the "this" pointer shall be adjusted when a method is invoked. In Java, there is no multiple inheritance, but an inner class can be used to provide a "view" of a given instance under another type.

Most of the time, it is possible to stick to single inheritance, but occasionally multiple inheritance would be the right tool to use, and this is the time to use an inner class.

This means that inner classes are somehow more complex than usual classes, in the same way that multiple inheritance is more complex than single inheritance: many programmers have some trouble wrapping their mind around that concept. Hence the "best practice": avoid inner classes because it confuses your coworkers. In my view, this is not a good argument, and at my workplace we are quite happy to use inner classes when we deem it appropriate.

(A minor drawback of inner classes is that they add one extra level of indentation in the source code. This is a bit irksome at times, when one wants to keep the code within 79 columns.)

Thomas Pornin
+2  A: 

In my view, 90% of inner classes in Java code are either entities that are associated with a single class and were thus "shoved in" as inner classes, or anonymous inner classes that exist because Java does not support Lambdas.

I personally don't like seeing complex inner classes. They add complexity to the source file, they make it bigger, they're ugly to deal with in terms of debugging and profiling, etc. I like separating my project into many packages, in which case I can make most entities top-level classes that are restricted to the package.

That leaves me with necessary inner classes - such as action listeners, fake "functional" programming, etc. These are often anonymous and while I'm not a fan (would have preferred a Lambda in many cases), I live with them but don't like them.

I haven't done any C# in years, but I'm wondering if the prevalence of inner classes or whatever the C# equivalent is dropped when they introduced Lambdas.

Uri
Agree but -1 for answering a dupe. You should know better.
finnw
+1  A: 

Anonymous inner classes are often used when we need to implement interface with one method, like Runnable, ActionListener and some other.

One more great appliance of anonymous inner classes is when you don't want to make a subclass of some class but you need to override one (or two) of its methods.

Named inner classes can be used when you want achieve tight coherence between two classes. They aren't so useful as anonymous inner classes and I can't be sure that it's a good practice to use them ever.

Java also has nested (or inner static) classes. They can be used when you want to provide some special access and standard public or default access levels aren't enough.

Roman
A: 

yes it is good to use them, when you are trying to keep a class cohesive, and the classes should never be instantiated from outside their context of the outer class, make the constructors private and you have really nice cohesive encapsulation. Anyone that says you should NEVER use them doesn't know what they are talking about. For event handlers and other things that anonymous inner classes excel at they are way better than the alternative of cluttering up your package namespace with lots of event handlers that only apply to a specific class.

fuzzy lollipop
+1  A: 

Inner classes are often used to "pass a behavior" as a parameter of a method. This capability is supported in an elegant way by other languages with closures. Using inner classes produces some not elegant code (IMHO) because of a language limitation but it's useful and widely used to handle events and blocks in general with inner classes.

So I would say that inner classes are very useful.

gicappa
+1  A: 

Anonymous inner classes has benefits in being able to see the fields and variables around the "new" statement. This can make for some very clean design and is a quite nice (but a bit wordy) approach to "how can we make a simple version of lambda statements".

Named inner classes has the benefit of having a name, hopefully telling, which can be documented in the usual way, but which is tied together to the surrounding class. A very nice example is the Builder pattern, where the inner class is responsible for providing state for the initialization process instead of having numerous constructors. Such builders cannot be reused between classes, so it makes perfect sense to have the Builder tied closely to the parent class.

Thorbjørn Ravn Andersen
+1  A: 

Yes, forbidding inner classes is a useful practice, in that finding out a place forbids them is a good way to warn me off working there, hence preserving my future sanity. :)

As gicappa points out, anonymous inner classes are the closest Java has to closures, and are extremely appropriate for use in situations where passing behaviour into a method is suitable, if nothing else.

Cowan
At least this one make me smile, and that's a good usage of sometime stupid rules found in company coding policies !
Guillaume