Java Forum / General / June 2005
static inner classes
Andersen - 22 May 2005 21:12 GMT Do I have to declare a (non-static) inner class inside the outer class or can I do it in a separate file? The problem I have at the moment is that I delcare the inner class in its own JAVA file, but then I cannot reference the outer class member attributes. How can I solve this problem? My files get too cluttered if I have all the inner classes declared and defined inside the outer class, this class I am talking of is already huge!
regards, Andersen
Andersen - 22 May 2005 21:12 GMT Sorry about the Subject line, it is misleading, I am talking about non-static inner classes, not static ones (I do want to refer to the outer class member attributes).
> Do I have to declare a (non-static) inner class inside the outer class > or can I do it in a separate file? The problem I have at the moment is [quoted text clipped - 6 lines] > regards, > Andersen John McGrath - 23 May 2005 12:42 GMT > I am talking about non-static inner classes, not static ones That's the only kind. Inner classes cannot be static.
 Signature Regards,
John McGrath
castillo.bryan@gmail.com - 23 May 2005 13:47 GMT Yes, they can.
castillo.bryan@gmail.com - 23 May 2005 14:10 GMT >>> I am talking about non-static inner classes, not static ones
>>That's the only kind. Inner classes cannot be static.
>Yes, they can. I didn't quote the article I was reffering to at first. I was just saying that yes, inner classes can be static.
John McGrath - 23 May 2005 14:22 GMT > >>> I am talking about non-static inner classes, not static ones > > > > That's the only kind. Inner classes cannot be static. > > > Yes, they can. No, they cannot. See JLS §8.1.2:
An inner class is a nested class that is not explicitly or implicitly declared static.
The correct term for a class declared within another class declaration is a *nested* class, not an *inner* class. An inner class is one that has an enclosing class instance.
 Signature Regards,
John McGrath
castillo.bryan@gmail.com - 25 May 2005 04:41 GMT > > >>> I am talking about non-static inner classes, not static ones > > [quoted text clipped - 10 lines] > a *nested* class, not an *inner* class. An inner class is one that has an > enclosing class instance. I just got that same terrible feeling, I got in college when I missed some trick question in my first C programming class. I remember the prof asking what some chunk of code output on the console. He would leave out a semi-colon and you were suppose to answer that "it wouldn't compile".
(It would have been nice if you had ellaborated your point in the first post. At least that way I wouldn't have been so embarrassed :) - Although I should used to being embarrassed on usenet!)
Thanks.
John McGrath - 25 May 2005 10:33 GMT > I just got that same terrible feeling, I got in college when I missed > some trick question in my first C programming class. I remember the > prof asking what some chunk of code output on the console. He would > leave out a semi-colon and you were suppose to answer that "it wouldn't > compile". My sympathies. I never understand why people think questions like that make sense. Do they not realize that compilers catch things like that for you? Or perhaps they think that distracting someone with minutiae will help them learn?
> (It would have been nice if you had ellaborated your point in the first > post. At least that way I wouldn't have been so embarrassed :) - > Although I should used to being embarrassed on usenet!) Sorry - that was not my intent. But that is certainly not a cause for embarrassment, considering how many people (including many authors) get it wrong. And besides, the point of participating in newsgroups is to learn. If we are expected to know everything already, why bother participating?
 Signature Regards,
John McGrath
deepaknemmini - 25 May 2005 12:28 GMT A nested class can be declared static (or not). A static nested class is called just that: a static nested class. A nonstatic nested class is called an inner class.
To help further differentiate the terms nested class and inner class, it's useful to think about them in the following way. The term nested class reflects the syntactic relationship between two classes; that is, syntactically, the code for one class appears within the code of another. In contrast, the term inner class reflects the relationship between objects that are instances of the two classes.
Chris Smith - 23 May 2005 14:34 GMT > >>> I am talking about non-static inner classes, not static ones > [quoted text clipped - 4 lines] > I didn't quote the article I was reffering to at first. I was just > saying that yes, inner classes can be static. This is simply not the case.
A nested class that is declared static is *not* an inner class. By definition, an inner class implicitly exists within the context of an instance of its outer class. By adding the 'static' keyword to something that would otherwise be an inner class, you have made it no longer an inner class; rather, it's only a nested class.
Nested classes are any class that's not top-level. Inner classes are a *subset* of nested classes, which aren't static. So it makes sense to talk about a static nested class, but not a static inner class. There was some confusion back in the 1.1 release cycle about this terminology, but Sun clarified it about six or seven years ago, and it's been the same since.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
John C. Bollinger - 23 May 2005 16:34 GMT >>>>I am talking about non-static inner classes, not static ones > [quoted text clipped - 4 lines] > I didn't quote the article I was reffering to at first. I was just > saying that yes, inner classes can be static. No, they cannot, but it's a matter of terminology. Inner classes are "nested classes" that are /not/ static. The other kind of nested classes are simply "static nested classes".
 Signature John Bollinger jobollin@indiana.edu
Dale King - 26 May 2005 04:46 GMT >>>>> I am talking about non-static inner classes, not static ones >> [quoted text clipped - 8 lines] > "nested classes" that are /not/ static. The other kind of nested > classes are simply "static nested classes". Unfortunately this terminology has changed over the years. The old terminology used in the ammendments and clarifications to the original JLS is confusing and contradictory. They have cleaned up the terminology in the version 2 of the JLS. Here is the new terminology, which should be used. Consider the old, confusing terminology of nested top-level classes and static inner classes as deprecated.
- There are top-level classes and nested classes. There is no such thing as a nested top-level class. A nested class is simply any class defined within another class.
- Nested classes come in two flavors, static nested classes and inner classes. Inner classes have an implicit link to an instance of the class they are declared within. They cannot be instantiated apart from an instance of their outer class. Static nested classes have no implicit link to an instance of the outer class. The term static inner class is now a contradiction in terms.
- Inner classes come in two varieties: named and anonymous.
 Signature Dale King
John C. Bollinger - 26 May 2005 15:49 GMT >>> I didn't quote the article I was reffering to at first. I was just >>> saying that yes, inner classes can be static. [quoted text clipped - 22 lines] > > - Inner classes come in two varieties: named and anonymous. Thanks, Dale, for the authoritative and full answer (exactly in line with what I wrote). Thanks also for reminding us all of how some of the confusion started in the first place.
 Signature John Bollinger jobollin@indiana.edu
Daniel Dyer - 26 May 2005 17:23 GMT >>> No, they cannot, but it's a matter of terminology. Inner classes are >>> "nested classes" that are /not/ static. The other kind of nested [quoted text clipped - 19 lines] > with what I wrote). Thanks also for reminding us all of how some of the > confusion started in the first place. It's worth also pointing out that there is another, rarely used, type of nested class - the local class. Josh Bloch calls the four types of nested classes as static member classes, non-static member classes, anonymous classes and local classes. Local classes are somewhere between non-static member classes and anonymous classes.
public class MyOuterClass { public void myMethod() { // Class that can only be instantiated within this method. class MyLocalClass { }
MyLocalClass myReference1 = new MyLocalClass(); MyLocalClass myReference2 = new MyLocalClass(); } }
Dan.
 Signature Daniel Dyer http://www.footballpredictions.net
Chris Uppal - 26 May 2005 19:19 GMT > It's worth also pointing out that there is another, rarely used, type of > nested class - the local class. Rarely used ? The anonymous class syntax is so revoltingly obfuscatory, and the semantics are so limited, that I don't willingly use anything other than "local classes" for inner classes.
-- chris
Dale King - 31 May 2005 12:27 GMT >> Thanks, Dale, for the authoritative and full answer (exactly in line >> with what I wrote). Thanks also for reminding us all of how some of >> the confusion started in the first place. It's in line with what you wrote, but what I wanted to point out was that the people using the old terminology were not wrong, just out of date. Originally they were called static inner classes and the oxymoron of top-level nested classes.
Thankfully they cleaned up the terminology, but we have to understand that people will still try to use the old terminology, because they aren't aware of the change.
> It's worth also pointing out that there is another, rarely used, type > of nested class - the local class. Josh Bloch calls the four types of > nested classes as static member classes, non-static member classes, > anonymous classes and local classes. Local classes are somewhere > between non-static member classes and anonymous classes. I was lumping local classes in with nested classes, thinking that they were really just nested classes with a smaller scope for the name, but thinking about it some more and checking I think it could be considered a special type as there are some slightly different rules (e.g. the ability to access final local variables).
I'll include that, because what I posted is one of the canned response for certain subjects that occur here frequently. Here is the added text:
- Named inner classes can be either class members (declared as a member of a class) or local (declared within a method).
 Signature Dale King
John McGrath - 27 May 2005 00:53 GMT > Inner classes have an implicit link to an instance of the class they are > declared within. They cannot be instantiated apart from an instance of > their outer class. Actually, this is not quite right. Local classes and anonymous classes that are declared in a static context are inner classes, but instances of these classes do not have an enclosing class instance.
 Signature Regards,
John McGrath
Thomas Schodt - 23 May 2005 14:12 GMT >>I am talking about non-static inner classes, not static ones > > That's the only kind. Inner classes cannot be static. The static keyword can be applied to inner classes. [Whatever that means.]
To OP.
<file: Inner.java> class Inner { ... } </file>
<file: Outer.java> class Outer { Inner getInstance() { return new Inner() { { // instance initializer block [anonymous class <init>()] // super(); - this would be implied? [try it] } void fubar() { } }; } } </file>
This should work.
Any methods that access Outer fields have to have their body in the anonymous inner class.
Remaining methods can be coded in Inner.java
It may be simpler to just add getter/setter methods?
Tor Iver Wilhelmsen - 23 May 2005 16:22 GMT > The static keyword can be applied to inner classes. No, to _nested_ classes. Inner classes is a particular sort of nested class that retains a non-null reference to an instance of its encolsing class.
Thomas Schodt - 23 May 2005 19:26 GMT > No, to _nested_ classes. Inner classes is a particular sort of nested > class that retains a non-null reference to an instance of its > enclosing class. I'm gonna remember this terminology for a few weeks or possibly months. Then I'll forget and go back to thinking of any class declared inside another class as "inner", be it static or not. I'll remember the difference the static keyword makes tho...
Bryan E. Boone - 27 May 2005 14:34 GMT >>The static keyword can be applied to inner classes. > > No, to _nested_ classes. Inner classes is a particular sort of nested > class that retains a non-null reference to an instance of its > encolsing class. I've always hear that in:
public class A { public static class B { .... } }
that B is referred to as a top-level nested class. -Bryan
Dale King - 01 Jun 2005 04:08 GMT >>> The static keyword can be applied to inner classes. >> [quoted text clipped - 11 lines] > > that B is referred to as a top-level nested class. Originally that was what Sun called it, but that name is an oxymoron. When they came out with the second edition of the JLS they cleaned up the terminology and terms like static inner classes and top-level nested classes are no longer used.
The new terminology is as follows:
- There are top-level classes and nested classes. There is no such thing as a nested top-level class. A nested class is simply any class defined within another class.
- Nested classes come in two flavors, static nested classes and inner classes. Inner classes have an implicit link to an instance of the class they are declared within. They cannot be instantiated apart from an instance of their outer class. Static nested classes have no implicit link to an instance of the outer class. The term static inner class is now a contradiction in terms.
- Inner classes come in two varieties: named and anonymous.
- Named inner classes can be either class members (declared as a member of a class) or local (declared within a method).
 Signature Dale King
Boudewijn Dijkstra - 22 May 2005 22:54 GMT > Do I have to declare a (non-static) inner class inside the outer class or > can I do it in a separate file? The problem I have at the moment is that I > delcare the inner class in its own JAVA file, but then I cannot reference > the outer class member attributes. How can I solve this problem? My files > get too cluttered if I have all the inner classes declared and defined > inside the outer class, this class I am talking of is already huge! The Java compiler normally copies a reference of the outer class object, to the inner class, via the constructor. This behaviour can easily be duplicated in separate inner and outer source files. If you want more details, you can disassemble a simple inner class.
Andersen - 22 May 2005 23:08 GMT >
> The Java compiler normally copies a reference of the outer class object, to > the inner class, via the constructor. This behaviour can easily be duplicated > in separate inner and outer source files. If you want more details, you can > disassemble a simple inner class. Does this relly work? What if the member attributes are of primitive type? Then you are making a deep/defensive copy to the inner class, and a change in any of the instances will not affect the other!
Wibble - 23 May 2005 03:07 GMT I think the point is, inner classes generate separate byte code files, so you can write your own compiler or byte code editor.
Of course, its alot simpler to define the 'inner' class as a regular class thats just references the 'outer' instance. You can't do the same visibility hacks as with inner classes, but they're a little smelly anyway.
Inner classes are really just syntactic sugar.
> > > [quoted text clipped - 6 lines] > type? Then you are making a deep/defensive copy to the inner class, and > a change in any of the instances will not affect the other! Boudewijn Dijkstra - 23 May 2005 11:27 GMT > > >> The Java compiler normally copies a reference of the outer class object, to [quoted text clipped - 4 lines] > Then you are making a deep/defensive copy to the inner class, and a change > in any of the instances will not affect the other! Just a reference to the outer class object is copied, not the members!
Andersen - 23 May 2005 16:01 GMT >>>The Java compiler normally copies a reference of the outer class object, to >>>the inner class, via the constructor. This behaviour can easily be [quoted text clipped - 6 lines] > > Just a reference to the outer class object is copied, not the members! How can it be a syntactic sugar, if the sugar translates to having references to the outer class member attributes, what happens to the outer class primitive attributes. They can be accessed, modified (given they're not final) by the inner class, but if you are just making a class that copies the references you cannot achieve this. I suspect something else is going on here.
regards, Andersen
Boudewijn Dijkstra - 23 May 2005 17:33 GMT >>>>The Java compiler normally copies a reference of the outer class object, >>>>to >>>>the inner class, via the constructor. This behaviour can easily be [quoted text clipped - 13 lines] > copies the references you cannot achieve this. I suspect something else is > going on here. Please read what I wrote. The outer class members (reference or primitive) are not copied, just a reference to the object holding these members (a.k.a. the outer class object).
For access to private members of the outer class, accessor methods are usually written by the compiler.
John McGrath - 23 May 2005 17:40 GMT > How can it be a syntactic sugar, if the sugar translates to having > references to the outer class member attributes, what happens to the > outer class primitive attributes. They can be accessed, modified (given > they're not final) by the inner class, but if you are just making a > class that copies the references you cannot achieve this. I suspect > something else is going on here. Assume we have a top-level class named Top that contains an inner class Top.Inner. You can transform it to a non-inner class as follows:
1) Move the declaration of class Inner from inside of Top to outside. 2) Add a private field (say "outer") of type Top to class Inner. 3) Add an argument of type Top to each constructor in class Inner. 4) In each constructor (that does not call another Inner constructor), set the value of the field "outer" from the argument value. 5) Change all references to Top members in Inner to use the "outer" field
This is essentially what the compiler does. There were almost no changes in the JVM specification required to implement nested (including inner) classes.
 Signature Regards,
John McGrath
Andersen - 23 May 2005 18:54 GMT Thank you very much for the answer, that settles it for me :-)
> Assume we have a top-level class named Top that contains an inner class > Top.Inner. You can transform it to a non-inner class as follows: [quoted text clipped - 9 lines] > in the JVM specification required to implement nested (including inner) > classes. John C. Bollinger - 23 May 2005 16:46 GMT > Do I have to declare a (non-static) inner class inside the outer class > or can I do it in a separate file? The problem I have at the moment is [quoted text clipped - 3 lines] > declared and defined inside the outer class, this class I am talking of > is already huge! At the source code level, you can create a class with many of the semantics of an inner class without lexically nesting it inside its outer class, but as a matter of terminology, it is not then an "inner class". The Java compiler does a fair amount of magic in some cases to make bytecode for nested classes that behaves according to the specs, and you may have to implement some of that directly in code if you want a class that has behavior similar to an inner class but whose source is not lexically nested in its "outer class"'s source.
You may, however, want to consider whether you could convert some of your inner classes into standalone classes, which then would not need to nest. In considering this refactoring, you might want to examine whether some of the top-level class' attributes might more appropriately belong to one or another of the currently nested classes -- if so (and I would expect it) then you may be able to resolve the attribute access issues by assigning the attributes to the appropriate classes.
 Signature John Bollinger jobollin@indiana.edu
Patricia Shanahan - 23 May 2005 18:27 GMT > Do I have to declare a (non-static) inner class inside > the outer class or can I do it in a separate file? The [quoted text clipped - 4 lines] > inner classes declared and defined inside the outer > class, this class I am talking of is already huge! You have a class that is already huge, and still growing. It is so huge that its size is getting in the way of the natural implementation of the new code. To me, your question yells "REFACTOR!".
Make sure you are not just assuming that the right division is between the code you already have and the code you are adding. Maybe there is a better split that would group the new code with some, but not all, of the existing code.
If the split between the new and the old code really is the best possible, presumably the new code is less tightly coupled to the rest of the code than any other piece in the existing class. Consider making it a separate class, with restricted interfaces to the existing class, rather than emulating an inner class. A large volume of code with common access to the same pool of attributes can be a maintainance nightmare.
Patricia
Larry Barowski - 24 May 2005 18:22 GMT > Do I have to declare a (non-static) inner class inside the outer class > or can I do it in a separate file? The problem I have at the moment is [quoted text clipped - 3 lines] > declared and defined inside the outer class, this class I am talking of > is already huge! What do you mean by huge? Is it more than 15kloc? I suspect you are worrying for no reason, but I could be wrong.
Furious George - 27 May 2005 00:00 GMT > Do I have to declare a (non-static) inner class inside the outer class > or can I do it in a separate file? The problem I have at the moment is [quoted text clipped - 3 lines] > declared and defined inside the outer class, this class I am talking of > is already huge! I don't know if this would work or not. My java skills are merely above average. Maybe some smarter people could say yea or nay.
Why not define your inner classes in separate interfaces? You can put as many or as few inner classes in each interface. Then make the outer class implement all the interfaces.
interface AInt { class AClass { } } ... interface ZInt { class ZClass { } } class Outer implements AInt ... ZInt { }
> regards, > Andersen
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|