• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Have a question about inner class

 
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,
I read the K&B books, in chapter 8, it said,
a regular inner class(not static,method-local,anonymous) can't have static declration of any kind.
I guess any kind means static methods or static variables.
But why?
Any ideas?
Thanks a lot.
 
Ranch Hand
Posts: 125
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The simple answer is: because the JLS says so. I also would like to know. Is it because of some difficulty in implementation, or some undesirable syntactic side effect, or is it arbitrary? Does anybody know?
 
Ranch Hand
Posts: 787
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Steve:
1. Inner class are members of outer class just like other variables and methods are members of outer class.
2. Other member var and member methods of outer class come in two flavours:
static and non-static.
3. Therefore, inner class also come in two flavours: static and non-static.
4. In K&B book, a non-static inner class is referred as regular inner class.
5. Just like a non-static member var can exist with an instance of class. There is no component of a non-static member var that is static.
6. Hence, there is no component of non-static inner classes (regular inner classes) that is static.
 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A lot of people ask and a few people try to explain why inner classes cannot have static members.
Jim Yingst has proposed a very convincing explanation. June 29, 2003 03:08 PM
 
Steve Lovelace
Ranch Hand
Posts: 125
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
VERY interesting thread!

Jim Yingst has proposed a very convincing explanation. June 29, 2003 03:08 PM

Actually, he only made a convincing argument for the case of local classes. He was not convincing at all about non-static member classes, which is the question opening this thread. He said:

[MM]: Perhaps inner member classes could have static fields?
Perhaps, but I think these would be subject to similar problems and confusions. Consider two InnerMember instances which were associated with two different instances of an Outer class. If Inner had a static field, should it have just one value for all Inner instances, or just for Inner instances associated with the same Outer instance? I would favor the latter, but again it would not be obvious, and again that static field of Inner could just be made a static or nonstatic field of Outer instead.


I disagree. If non-static member classes (referred to as "inner member" in the above - more on that below) could have static members, they should definitely have one set of static data, just like their static brethren. How then could they be any more confusing than static member classes? The only distinction between the two would be that non-static member classes require an enclosing instance of their enclosing class for instantiation.
Now we ("we" I say, assuming you aren't ) are on to my favorite subject, which Marlene, you may remember from my hammering on it in some other thread ("ah yes", she cringes).
Consider that we must categorize nested classes three ways (Marlene performs this exercise in the above mentioned thread).
1. Scope.
  • Member classes
  • Local classes
  • Anonymous classes

  • 2. Inner. This category simply excludes static member classes for the purpose of saying "can't have static members".

    3. Needs-enclosing-instance-of-enclosing-class.
  • Non-static member classes
  • local classes declared in non-static contexts
  • anonymous classes declared in non-static contexts
  • Note that category #3 is really really important in understanding and using nested classes. Note that it has no good name.
    Note that category #2 is merely "not static member class", and as per the discussion in this thread is sort of fishy, AND is sitting on the pithy label that would be so nice to use for category #3.
    SO-O (don't now). If non-static member classes could have static members, category #2 would disappear. It would just be stated that only member classes can have static members. Then there would only be two ways to categorize nested classes, and, best of all, the second category wouldn't be called needs-an-enclosing-instance-of-the-enclosing-class; it would be called inner.
    So I've snuck in my rant one more time Why do I do it? Because, people slide terms around, especially "inner", or invent new ones ("inner member" here, "regular inner" in K&B). Everybody does it. It's because there is currently no adequate mapping of terms to structure in nested classes, and so discussions of them tend to be muddy. It makes them seem more confusing than they actually are, creating a real obstacle when trying to learn them and constant annoyance thereafter.
    Whew! I'm done. Better not start me up again (and to make it all so much worse, I've discovered graemlins ). Unless of course, you'd like to poke holes in this.
    [ September 17, 2003: Message edited by: Steve Lovelace ]
     
    Barkat Mardhani
    Ranch Hand
    Posts: 787
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Posted by Steve:

    I disagree. If non-static member classes (referred to as "inner member" in the above - more on that below) could have static members, they should definitely have one set of static data, just like their static brethren. How then could they be any more confusing than static member classes? The only distinction between the two would be that non-static member classes require an enclosing instance of their enclosing class for instantiation.


    Hi Steve,
    Looks like my last post was not convincing enough. Here I am taking a different approach to make my point.
    Let us assume that member level inner classes could have static variables.

    Line 1 and 2 will not compile. Let us say they do. The output will be:
    5 0
    5 1
    5 3
    Now let us change the code:

    The output will be:
    5 0
    5 1
    5 2
    The point is that you want as static inner class var can be easily implemented as outer class instance level var. However, later solution is simpler than former and provides same functionality. I guess that is why Sun dedided to with later.
    Thanks
    Barkat
     
    Steve Lovelace
    Ranch Hand
    Posts: 125
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Barkat:
    I believe you're pointing out that since static vars of the outer class are visible to the inner class, allowing their declaration in the inner class could be looked at as redundant. Of course, I could argue by extension that the instance vars of Outer are also visible to Inner, so their declaration in Inner is also redundant. So by extension there is no point in allowing any member vars in Inner - we can just declare them all in Outer. I'm following out this reasoning to point up a very good reason for allowing member classes to declare member variables, static and instance: scoping. Declaring variables to have scope larger than the context in which they are actually used is a source of bugs.
    But my point isn't really about that. It's about the way we think and talk about nested classes, the fact that it is conflicted, and that a small tweak in the rules about member classes would undo much of the knottiness.
    [ September 17, 2003: Message edited by: Steve Lovelace ]
     
    Barkat Mardhani
    Ranch Hand
    Posts: 787
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Posted by Steve

    I believe you're pointing out that since static vars of the outer class are visible to the inner class, allowing their declaration in the inner class could be looked at as redundant. Of course, I could argue by extension that the instance vars of Outer are also visible to Inner, so their declaration in Inner is also redundant. So by extension there is no point in allowing any member vars in Inner - we can just declare them all in Outer. I'm following out this reasoning to point up a very good reason for allowing member classes to declare member variables, static and instance: scoping. Declaring variables to have scope larger than the context in which they are actually used is a source of bugs.
    But my point isn't really about that. It's about the way we think and talk about nested classes, the fact that it is conflicted, and that a small tweak in the rules about member classes would undo much of the knottiness.
    [ September 17, 2003: Message edited by: Steve Lovelace ]


    Response first bolded region:
    I meant to say that the static varable i.e. innerClassStaticVar (if allowed) in a member level inner class will be equivalent to a instance variable (outerClassInstanceVar) of outer class. So it makes sense to use latter.
    Response to second bolded region:
    There is a difference between outer class's instance variable and inner class variable.
    One Outer Class Instance can have many outer instances.
    Each outer instance can have many member level inner class instances.
    So it is one-many-many relationship.
    [ September 17, 2003: Message edited by: Barkat Mardhani ]
     
    Ranch Hand
    Posts: 183
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I am a little offtopic here but this is something that I memorized and have never found out the reason for it.
    When declaring a non static inner class, what is it as such:
    OuterClass oc = new OuterClass();
    OuterClass.InnerClass ic[] = new OuterClass.InnerClass [3];

    and not
    oc.InnerClass ic[] = new oc.InnerClass [3];
    ???
     
    Barkat Mardhani
    Ranch Hand
    Posts: 787
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    posted by Ed:

    oc.InnerClass ic[] = new oc.InnerClass [3];


    I guess when declaring types for new variables, they have to be actual names of class. I do not think compiler will take time to find type of oc and plug in there. Instead it will think of oc as a package and give error that oc package was not found.
    Thanks
    Barkat
     
    Steve Lovelace
    Ranch Hand
    Posts: 125
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Barkat:
    Yes, you're right. I completely missed the one-to-many relationship in my "argument by extension". Still hold to my contention though, that static members should be permitted in ANY member class, and for two reasons: 1) scoping as mentioned above 2) static and non-static member classes, just like static and non-static (instance) methods, should differ only in that the latter can see the instance members of the enclosing class. This would make the whole nested class structure much much cleaner.
     
    Ranch Hand
    Posts: 443
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Let me throw my 2 cents to this discussion.
    First, my perspective about static members (be it variable, method or nested class).
    I believe that the main characteristic of a static member is that it is not meant to be bound to any instance. Static members as simply names that requires a namespace to be bound to. In Java, the only way to bind a static member to a namespace is if you define it in a class.
    But if it is possible, in my opinion, some static members should be bounded to a package only. For example, the members of the Math class could have been defined in a Math package without having the need to create a Math class. The class itself is useless because you hardly instantiate it. In Python, for example, you can declare a functions that is bound to a 'Module'(modules are like packages), without being bound to a class.
    Inner classes requires an instance of the enclosing class. So if you define a static member inside an inner class, you are binding it to an instance, something that is not meant for a static members. Even if you define a local class in a static method, the class itself will not survive outside the method, although its instance can. So if you define it there, then you are still binding it to an instance.
    Just my opinion.
     
    Steve Lovelace
    Ranch Hand
    Posts: 125
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Alton:
    Inner classes requires an instance of the enclosing class.
    I want this to be true, but it isn't. I want this to be the definition of inner. This is a large part of why I'm writing these frightful essays.
    So if you define a static member inside an inner class, you are binding it to an instance, something that is not meant for a static members.
    There is no reason why static members would be bound to an instance. The inner class has its Class object and the static members can be bound to that. This may already be happening. As Marlene pointed out recently, the assert mechanism is sneaking unseen static members into inner classes. I'd love to know the details.
    Even if you define a local class in a static method, the class itself will not survive outside the method, although its instance can. So if you define it there, then you are still binding it to an instance.
    To what instance is it bound? There simply is no enclosing instance. This is a little off topic anyway since we are talking about member classes, which do not evaporate from the stack.
     
    Alton Hernandez
    Ranch Hand
    Posts: 443
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Steve Lovelace:
    I want this to be true, but it isn't. I want this to be the definition of inner. This is a large part of why I'm writing these frightful essays.


    Ok, I think I should use the right terminology. What I was actually talking here are Non-Static Member Classes only. My reasoning for the other types of inner classes are mentioned in the 3rd quotation.

    Originally posted by Steve Lovelace:
    There is no reason why static members would be bound to an instance. The inner class has its Class object and the static members can be bound to that. This may already be happening. As Marlene pointed out recently, the assert mechanism is sneaking unseen static members into inner classes. I'd love to know the details.


    Well, I guess if Sun wants to, they can. But my argument basically was that static members are pretty much independent, and the only reason why we put them in a class, I guess, is because that is the simpliest namespace that they can have. So putting them in an instance is not necessary.

    Originally posted by Steve Lovelace:
    To what instance is it bound? There simply is no enclosing instance. This is a little off topic anyway since we are talking about member classes, which do not evaporate from the stack.


    They will be bound to the instance of the local class you defined in that method.
    How can you use the local class outside of that method unless you create an instance of it (as in line 3)?

    However, if you are just using it inside the enclosing method(as in line 2), then I don't see the point of it.
    [ September 19, 2003: Message edited by: Alton Hernandez ]
     
    Steve Lovelace
    Ranch Hand
    Posts: 125
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    This conversation is like every other nested class conversation. You say "inner", and then a couple of paragraphs later, or a response later, are obliged to state what you really meant by "inner".
    It's always like that, and that is what my rant is about. You are very ably pointing out practical considerations which allow you to say, on good grounds, what's the point of static members in non-static member classes? (Though apparently Sun has found a point.)
    It's like when you're programming along and notice that there are too many if-statements, that they're getting 2 or 3 deep, or you're having to make too many chained method invocations, or your thinking about writing a facade just to put a nice face on a kluge. You know in your bones then that something is wrong. Programming is dividing and reuniting, right? We break the problem into components and assemble the components into a solution. When the assembly end is getting overgrown with qualifications, we know that something went wrong at the breaking-apart end.
    This is what nested classes feels like. We should be able to make simple statements about nested classes like
  • An inner class is a nested class which can see its enclosing classes' instance members
  • An inner class instance requires an enclosing instance of its enclosing class.
  • Only member classes can have static members.
  • The only difference between a static member class and a non-static member class, is that the non-static class is inner.

  • We don't have that. To describe the current situation, every one of those statements has to be replaced with something more complicated.
    My proposition is that one tweak, allowing static members in non-static member classes, would enable this simplification.
     
    Alton Hernandez
    Ranch Hand
    Posts: 443
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Steve,

    Originally posted by Steve Lovelace:
    This conversation is like every other nested class conversation. You say "inner", and then a couple of paragraphs later, or a response later, are obliged to state what you really meant by "inner".


    I used the term "inner" because that is the term used by the originator of this thread; and I don't want to confuse people more by introducing terms such as method-local, nested class, non-static members.

    Originally posted by Steve Lovelace:
    It's always like that, and that is what my rant is about.


    I think I fully understand your rant. There are some of us who would like to see some changes in the language, but perhaps powerless to do so.

    Originally posted by Steve Lovelace:
    You are very ably pointing out practical considerations which allow you to say, on good grounds, what's the point of static members in non-static member classes? (Though apparently Sun has found a point.)


    Your views are taken from the point of Nested classes - mine are from static members. So therein lies the difference. We are coming from different directions but somehow these 2 issues crossed at some point.
    If you think that the concept of "inner" class now is broken, and one way to fix that is by allowing static members in, then I say you are doing that at the expense of the concept of static members(assuming my assumption about static members is right,of course).
     
    Steve Lovelace
    Ranch Hand
    Posts: 125
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Ah, so what is your conception of "static"? Mine is this:
    A static member is associated with ("bound to") the Class object.
    The classLoader loads a class description producing a Class object. A well-behaved classLoader will not produce a second Class object for the same class name, so there is only one. Linking and initializing then occurs on that Class object. Part of this is initialization of static fields. So even though the JLS doesn't make a statement about static like mine (or at least I haven't found one), it pretty much implies that it's so.
    This brings up another question: What prevents ANY class from having static members? There is a Class object available. (And maybe with assert related static members lurking behind the scenes, this question is already answered.)
     
    reply
      Bookmark Topic Watch Topic
    • New Topic