This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Tarun Oohri wrote:1. Why it is that we can not define anything static inside the regular inner class (not talking about the static inner class).
I suspect it's to keep things simple, although there may also be some structural reasons. But think of it this way: Why do we define static fields to begin with? Generally so that we have something that is globally accessible, either from inside a class (if it's private) or the public at large (if it's public).
Since nested classes are fully visible to their enclosing class, you can't hide a static field by putting it in an inner class, and since there's only ever going to be 1 copy of it, it really doesn't matter whether you define it in the inner class or it's outer one.
There might, however, be a reason for defining a static constant inside an inner class, the most obvious of which is readability - ie, it just makes more sense to name the field in the context of the inner class, because that's where it has a meaning. But, as I hope you know, constants are final.
It may also be worth mentioning that true inner classes (ie, non-static nested classes) are really quite rare, and are usually used to hide an internal implementation, so they're usually private. Some Maps, for example, use them to hold their keys as a Set, which is what you get when you call the keySet() method.
Static nested classes, on the other hand, are much more common, and are just like a regular class - it just happens to be defined inside another one, usually because that's the only place where it makes sense. A good example of a class like that is AbstractMap.SimpleEntry which, as it turns out, implements a nested interface: Map.Entry.
Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
I don't think true inner classes are all that rare - but the most common example is anonymous classes, where it's often not that they need to be non-static to access some instance member, but that's just the way the language set up anonymous classes. However named true inner classes aren't all that rare either - most of the collections implementations have at least one, used for an Iterator implementation for example. Because an Iterator is designed to access data in the instance it's iterating, it's a natural use case for an inner class.
I would agree that named inner classes are considerably less common than either static nested classes or anonymous classes. But "really quite rare" seems an overstatement to me.
Mike Simmons wrote:I don't think true inner classes are all that rare - but the most common example is anonymous classes
Yeah, you're right. I should probably have said 'named'. The thing is, I don't really see anonymous classes as 'inner' or 'nested', although I understand that structurally, that's exactly what they are. To me, they're basically a mechanism for creating a temporary object without a lot of hassle.
And I've probably created 10-20 static nested classes for every named non-static one in my programming life; but whether that makes them 'rare' or not, I'm not quite sure. Can we settle on 'uncommon'?
My point was that if you're creating a named nested class, put static on it unless you have a very good reason not to.
Tarun Oohri wrote:
1. Why it is that we can not define anything static inside the regular inner class (not talking about the static inner class).
We can define static variables but then they must be final.
To be exact, this exception to the rule, is an exception for compile time constant variables. So, the variable must be more than just final -- it also needs to be assigned to a constant expression, assigned at declaration, and of a type that can be a compile time constant. Otherwise, it will not be a compile time constant variable, and will not be allowed.