statics in inner classes

Discussion in 'Java' started by Roedy Green, Jul 1, 2005.

  1. Roedy Green

    Roedy Green Guest

    I think I almost have it understanding inner, nested, top-level,
    public etc classes and the equivalent enums.

    What I don't understand is the restriction on no static variables in
    inner nested non-static instance classes. Why?

    What puzzles me is it seems ok to derive inner classes from a class
    that has some static variables. It only seems upset about new statics.

    I finally figured out why you can only access final enclosing local
    variables in your anonymous inner classes.

    I am gradually putting it together and will post in the next day or
    two at http://mindprod.com/jgloss/innerclasses.html

    The other puzzle is why enums constructors cannot access static
    fields.



    --
    Bush crime family lost/embezzled $3 trillion from Pentagon.
    Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

    Canadian Mind Products, Roedy Green.
    See http://mindprod.com/iraq.html photos of Bush's war crimes
    Roedy Green, Jul 1, 2005
    #1
    1. Advertising

  2. Roedy Green

    Chris Smith Guest

    Roedy Green <> wrote:
    > What I don't understand is the restriction on no static variables in
    > inner nested non-static instance classes. Why?


    It appears to be just an arbitrary rule. There is certainly an obvious
    behavior that could have been assigned to it, but Sun decided against
    it, for whatever reason. I wouldn't hunt for clues to anything
    profound.

    > What puzzles me is it seems ok to derive inner classes from a class
    > that has some static variables. It only seems upset about new statics.


    Since static members are not inherited, that's really not a problem.

    > The other puzzle is why enums constructors cannot access static
    > fields.


    I'm unaware of such a restriction. At least, the following code
    compiles with Eclipse 3.1RC3.

    public enum Test
    {
    A(42), B(7)

    ;

    static int a = 5;
    public int aa;

    Test(int val)
    {
    aa = val * a;
    }
    }

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Jul 1, 2005
    #2
    1. Advertising

  3. Chris Smith <> writes:

    > Roedy Green <> wrote:
    >> The other puzzle is why enums constructors cannot access static
    >> fields.

    >
    > I'm unaware of such a restriction. At least, the following code
    > compiles with Eclipse 3.1RC3.


    But did you test it? Both Test.A.aa and Test.B.aa has the value 0.

    > public enum Test
    > {
    > A(42), B(7)


    This corresponds to the declarations:

    public static final A = new Test(42);
    public static final B = new Test(42);

    however ...

    > static int a = 5;


    the static variable "a" only gets its value later, so at the time of
    creation of A and B, it has the default value.

    To confuze it even more, had you made "a" final, it would have been a
    constant, and would be inlined without a problem.


    I'm not sure what Roedy Green's problem is, excatly. Enum constructors
    can access static fields just fine, they just have to consider when
    they are doing it ... which is before static initialiation reaches
    the assignments to static fields.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Jul 1, 2005
    #3
  4. Roedy Green

    Chris Smith Guest

    Lasse Reichstein Nielsen <> wrote:
    > > I'm unaware of such a restriction. At least, the following code
    > > compiles with Eclipse 3.1RC3.

    >
    > But did you test it? Both Test.A.aa and Test.B.aa has the value 0.


    Ah. I missed that; another ugly implementation artifact. Thanks for
    pointing it out!

    Unfortunately, these kinds of things are building up, making Java into a
    language that has to be learned from version 1.0 forward, instead of
    making sense statically in its current form.

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Jul 1, 2005
    #4
  5. Roedy Green

    Roedy Green Guest

    On Fri, 1 Jul 2005 09:34:38 -0600, Chris Smith <> wrote
    or quoted :

    >It appears to be just an arbitrary rule. There is certainly an obvious
    >behavior that could have been assigned to it, but Sun decided against
    >it, for whatever reason. I wouldn't hunt for clues to anything
    >profound.


    I've been chewing on it. One thing that hit me is it may speed garbage
    collection. Classes I think are harder to scavenge that object. You
    don't want millions of little throwaway class objects littering the
    pool. By refusing static members, you can dispense with a separate
    class object for each anonymous class.

    --
    Bush crime family lost/embezzled $3 trillion from Pentagon.
    Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

    Canadian Mind Products, Roedy Green.
    See http://mindprod.com/iraq.html photos of Bush's war crimes
    Roedy Green, Jul 2, 2005
    #5
  6. Roedy Green

    Chris Smith Guest

    Roedy Green <> wrote:
    > I've been chewing on it. One thing that hit me is it may speed garbage
    > collection. Classes I think are harder to scavenge that object. You
    > don't want millions of little throwaway class objects littering the
    > pool. By refusing static members, you can dispense with a separate
    > class object for each anonymous class.


    No, you definitely need a separate Class object (and all the other
    underlying class stuff) for each anonymous inner class. Anonymous
    classes are treated in exactly the same way as any other class, and the
    JVM generally doesn't even pay attention to the difference.

    I don't think it would matter anyway. Class GC is done per class
    loader, so unless you added additional class loaders, there isn't any
    additional work to be done in garbage collection. An anonymous class is
    ALWAYS loaded by the same classloader as its containing class (or
    conceivably by its ancestor, but that requires strange contortions).

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Jul 2, 2005
    #6
  7. Chris Smith wrote:
    > Roedy Green <> wrote:
    >
    >>What I don't understand is the restriction on no static variables in
    >>inner nested non-static instance classes. Why?

    >
    >
    > It appears to be just an arbitrary rule. There is certainly an obvious
    > behavior that could have been assigned to it, but Sun decided against
    > it, for whatever reason. I wouldn't hunt for clues to anything
    > profound.
    >


    According to the specification, inner classes may have static fields
    that are compile time constants. So there's one of those clues you
    suggested we not hunt for.

    Ray

    --
    XML is the programmer's duct tape.
    Raymond DeCampo, Jul 2, 2005
    #7
  8. "Chris Smith" <> wrote in message
    news:...
    > Roedy Green <> wrote:
    >> What I don't understand is the restriction on no static variables in
    >> inner nested non-static instance classes. Why?

    >
    > It appears to be just an arbitrary rule. There is certainly an obvious
    > behavior that could have been assigned to it, but Sun decided against
    > it, for whatever reason. I wouldn't hunt for clues to anything
    > profound.


    Me neither, but I would offer a possibility. Well actually, more
    accurately, they are stray thoughts forming in me head.

    Throughout the documentation, sun seems to regard inner classes as members
    of enclosing instances. Basically, even though it looks like a simple class
    namespace issue, it actually regards the inner class as a member, with rules
    similar to other members. I of course am very likely to have this wrong,
    but it seems this way, perhaps I'll go dig up what I'm referring to today.

    Take for example, one of the goofiest things in java:

    X.Y xy = new X().new Y();

    For when Y is a non-static class it requires the context of the X /object/
    to instantiate it. Where as when Y is a static inner:

    X.Y xy = new X.Y();

    Works just fine. So going back to:

    new X().new Y();

    The inner class Y is (perhaps?) not able to have a static member because
    there is no static class for it to belong to? That is, X, the outer class
    is (perhaps?) by definnition an implied static. The inner however, is not,
    and therefore there is no class per se to actually contain the statics.

    This is far from a connecting of the dots, and is likely wrong, but it's the
    best I can do right now.







    >
    >> What puzzles me is it seems ok to derive inner classes from a class
    >> that has some static variables. It only seems upset about new statics.

    >
    > Since static members are not inherited, that's really not a problem.
    >
    >> The other puzzle is why enums constructors cannot access static
    >> fields.

    >
    > I'm unaware of such a restriction. At least, the following code
    > compiles with Eclipse 3.1RC3.
    >
    > public enum Test
    > {
    > A(42), B(7)
    >
    > ;
    >
    > static int a = 5;
    > public int aa;
    >
    > Test(int val)
    > {
    > aa = val * a;
    > }
    > }
    >
    > --
    > www.designacourse.com
    > The Easiest Way To Train Anyone... Anywhere.
    >
    > Chris Smith - Lead Software Developer/Technical Trainer
    > MindIQ Corporation
    Thomas G. Marshall, Jul 9, 2005
    #8
  9. Roedy Green

    Roedy Green Guest

    On Sat, 09 Jul 2005 16:02:48 GMT, "Thomas G. Marshall"
    <> wrote or quoted
    :

    > The inner however, is not,
    >and therefore there is no class per se to actually contain the statics.


    If there were statics for inner classes what are they -- one class per
    set of objects tied to mother? or to me more logical one class per set
    of such objects ever created anywhere.


    What happens when your inner class extends a class that already has
    some statics? Does it stop you?

    --
    Bush crime family lost/embezzled $3 trillion from Pentagon.
    Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

    Canadian Mind Products, Roedy Green.
    See http://mindprod.com/iraq.html photos of Bush's war crimes
    Roedy Green, Jul 10, 2005
    #9
  10. Roedy Green <> writes:

    > If there were statics for inner classes what are they -- one class per
    > set of objects tied to mother?


    That would be consistent. A member class belongs to the enclosing
    instance, so there really is one class per enclosing instance. It's
    just not implemented like that under the hood, but that is the idea.

    > What happens when your inner class extends a class that already has
    > some statics? Does it stop you?


    Extending a class that contains static members will allow you to
    access the members through the extending type as well. But that's just
    being nice. They are still resolved, at compile time, to the static
    members of the class declaring them, and the compiled bytecode need
    not refer to the extending class at all.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Jul 10, 2005
    #10
  11. Roedy Green coughed up:
    > On Sat, 09 Jul 2005 16:02:48 GMT, "Thomas G. Marshall"
    > <> wrote or quoted
    >>

    >
    >> The inner however, is not,
    >> and therefore there is no class per se to actually contain the
    >> statics.

    >
    > If there were statics for inner classes what are they -- one class per
    > set of objects tied to mother?


    I'm sorry, I don't understand this statement.


    > or to me more logical one class per set
    > of such objects ever created anywhere.


    Nor this one. Can you rephrase?


    > What happens when your inner class extends a class that already has
    > some statics? Does it stop you?


    From what, adding further statics? You cannot. From accessing the existing
    ones in the super class? You can, but only because java allows you to
    access superclass statics from extended classes (and I'm not particularly
    glad about that, since it seems a break in what statics should be (belonging
    to a class, not a class hierarchy), but thems the facts, and it doesn't hurt
    the discussion any).

    If you have these classes:

    A
    X
    X.Y

    And this in A:

    public static int num;

    and this relationship

    A <|-- X.Y

    Then accessing X.Y.num is always possible. I don't like it much, but it's
    true of any subclass of a class holding a static. For yucks, this would be
    the test app:

    class A
    {
    static int num = 5;
    }

    public class StaticTest
    {
    class B extends A
    {
    static int cant = 6; // compile error
    }

    public static void main(String[] args)
    {
    System.out.println("Can access B.num---> " + B.num);
    }
    }




    --
    Sometimes life just sucks and then you live.
    Thomas G. Marshall, Jul 11, 2005
    #11
  12. Roedy Green

    Roedy Green Guest

    On Mon, 11 Jul 2005 01:21:00 GMT, "Thomas G. Marshall"
    <> wrote or quoted
    :

    >> If there were statics for inner classes what are they -- one class per
    >> set of objects tied to mother?

    >
    >I'm sorry, I don't understand this statement.


    Does conceptually there a different class object allocated per
    instance of the mother object or is there one shared by all.

    Perhaps the restriction on no statics was to avoid deciding what it
    means.


    In other would statics on an inner class be for communication between
    inner class members of a gives object only, or between inner class
    members of all inner class objects no matter what object they are
    attached to.


    By not allowing statics they avoid the question.

    --
    Bush crime family lost/embezzled $3 trillion from Pentagon.
    Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

    Canadian Mind Products, Roedy Green.
    See http://mindprod.com/iraq.html photos of Bush's war crimes
    Roedy Green, Jul 11, 2005
    #12
  13. Thomas Schodt, Jul 11, 2005
    #13
  14. "Roedy Green" <> wrote in message
    news:...
    > On Mon, 11 Jul 2005 01:21:00 GMT, "Thomas G. Marshall"
    > <> wrote or quoted
    > :
    >
    >>> If there were statics for inner classes what are they -- one class per
    >>> set of objects tied to mother?

    >>
    >>I'm sorry, I don't understand this statement.

    >
    > Does conceptually there a different class object allocated per
    > instance of the mother object or is there one shared by all.
    >
    > Perhaps the restriction on no statics was to avoid deciding what it
    > means.
    >
    >
    > In other would statics on an inner class be for communication between
    > inner class members of a gives object only, or between inner class
    > members of all inner class objects no matter what object they are
    > attached to.
    >
    >
    > By not allowing statics they avoid the question.


    Not to avoid the question per se, but yes, you're on the right track. Since
    they are part of enclosing *instances*, having a static belong to it is a
    no-no.

    (Please, no one here who is junior confuse this with accessing a static from
    an object).


    >
    > --
    > Bush crime family lost/embezzled $3 trillion from Pentagon.
    > Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
    > http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
    >
    > Canadian Mind Products, Roedy Green.
    > See http://mindprod.com/iraq.html photos of Bush's war crimes
    Thomas G. Marshall, Jul 11, 2005
    #14
  15. Roedy Green coughed up:
    > On Mon, 11 Jul 2005 01:21:00 GMT, "Thomas G. Marshall"
    > <> wrote or quoted
    >>

    >
    >>> If there were statics for inner classes what are they -- one class
    >>> per set of objects tied to mother?

    >>
    >> I'm sorry, I don't understand this statement.

    >
    > Does conceptually there a different class object allocated per
    > instance of the mother object or is there one shared by all.
    >
    > Perhaps the restriction on no statics was to avoid deciding what it
    > means.
    >
    >
    > In other would statics on an inner class be for communication between
    > inner class members of a gives object only, or between inner class
    > members of all inner class objects no matter what object they are
    > attached to.
    >
    >
    > By not allowing statics they avoid the question.


    Roedy, it's of course up to you, but I would think that you might want an
    example at least *similar* to my

    X.Y xy = new X().new Y(); // non-static inner Y

    vs.

    X.Y xy = new X.Y(); // static inner Y

    to eventually make it to your jgloss. I believe that the top formalism for
    non-static inner classes is flat-out unknown to a vast majority of java
    engineers.

    It helps to explain why the following is not allowed (and it confuses nearly
    every beginner):

    public class Static3
    {
    // NON-STATIC inner class
    class Inner
    {
    }

    public static void main(String[] args)
    {
    // following disalllowed:
    // "non-static variable this cannot be
    // referenced from a static context"
    Inner inner = new Inner();
    }
    }

    $ com Static3.java
    javac 1.5.0-beta2
    Static3.java:17: non-static variable this cannot be referenced
    from a static context
    Inner inner = new Inner();
    ^
    1 error
    $

    It is complaining about the variable "this". This is implied:

    Inner inner = this.new Inner();

    ....because Inner is not static. This is the same error message when any
    member variable is accessed from a static context:

    public class Static4
    {
    int num = 5;

    public static void main(String[] args)
    {
    int x = num;
    }
    }


    $ com Static4.java
    javac 1.5.0-beta2
    Static4.java:11: non-static variable num cannot be referenced
    from a static context
    int x = num;
    ^
    1 error
    $


    --
    Having a dog that is a purebred does not qualify it for breeding. Dogs
    need to have several generations of clearances for various illnesses
    before being bred. If you are breeding dogs without taking care as to
    the genetic quality of the dog (again, being purebred is *not* enough),
    you are what is known as a "backyard breeder" and are part of the
    problem. Most of the congenital problems of present day dogs are
    traceable directly to backyard breeding. Spay or neuter your pet
    responsibly, and don't just think that you're somehow the exception and
    can breed a dog without taking the care described.
    Thomas G. Marshall, Jul 12, 2005
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. lonelyplanet999
    Replies:
    1
    Views:
    2,211
    VisionSet
    Nov 13, 2003
  2. Razvan
    Replies:
    5
    Views:
    11,297
    Dale King
    Jul 27, 2004
  3. Carlo v. Dango
    Replies:
    14
    Views:
    1,025
    Alex Martelli
    Oct 19, 2003
  4. Pyenos
    Replies:
    2
    Views:
    385
    Pyenos
    Dec 27, 2006
  5. Stuart MacMartin
    Replies:
    5
    Views:
    556
    Victor Bazarov
    Jul 27, 2005
Loading...

Share This Page