I have always wondered why static inner classes can have static
members but ordinary inner classes cannot. It seems a strange
anti-orthogonality.
Why? It would at first glance seem more work to treat them specially.
Is there some difficulty in implementation? Is there some reason why
stylistically the statics would be wicked?

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Lew - 10 Aug 2007 00:12 GMT
> I have always wondered why static inner classes can have static
> members but ordinary inner classes cannot. It seems a strange
[quoted text clipped - 3 lines]
> Is there some difficulty in implementation? Is there some reason why
> stylistically the statics would be wicked?
I speculate it was to simplify notational cruft and difficulties of
implementation.
I've always been confused by whether a putative inner static would need an
enclosing instance, leading to weird notational idiomata:
new Foo().Bar.illegalStaticString = "";
or whether such a static would be static across all enclosing instances of the
inner class objects:
Foo.Bar.illegalStaticString = "";
Would a static inner-class method have access to any enclosing instance
attributes?
I suspect the choices matter at a low level in either the compiler or the JVM
and would've been difficult.

Signature
Lew
Roedy Green - 10 Aug 2007 00:23 GMT
>or whether such a static would be static across all enclosing instances of the
>inner class objects:
I assumed they would be. The statics would be primarily for static
final constants local only to that inner class.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Lew - 10 Aug 2007 02:03 GMT
Lew wrote:
>> or whether such a static would be static across all enclosing instances of the
>> inner class objects:
> I assumed they would be. The statics would be primarily for static
> final constants local only to that inner class.
But compile-time constants are legal:
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3>
> Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).
...
> class HasStatic{
> static int j = 100;
[quoted text clipped - 9 lines]
> interface NeverInner{} // interfaces are never inner
> }

Signature
Lew
Roedy Green - 10 Aug 2007 23:23 GMT
>But compile-time constants are legal:
>http://java.sun.com/docs/books/jls/
>third_edition/html/classes.html#8.1.3
>Inner classes may not declare static members,
>unless they are compile-time constant fields (15.28)
Seems to me javac rejected something of this form in an inner class.
private static final int X;
static
{
int temp = something;
X = expression;
}

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Mike Schilling - 11 Aug 2007 00:01 GMT
>> But compile-time constants are legal:
>> http://java.sun.com/docs/books/jls/
[quoted text clipped - 8 lines]
> X = expression;
> }
That's not a compile-time constant. A compile-time constant's value is set
in the declaration, and result in the field's value being explcitly stored
in the class file, so that it's available at compile time. That's what
causes this odd-seeming behavior:
Class1.java:
public static final int i = 12;
Class2.java:
System.out.println(Class1.i);
This will, of course, print "12". If you change i's value to 13 and
recompile Class1, it continues to print 12 until you recompile Class2.
Lew - 11 Aug 2007 01:27 GMT
>>> But compile-time constants are legal:
>>> http://java.sun.com/docs/books/jls/
[quoted text clipped - 24 lines]
> This will, of course, print "12". If you change i's value to 13 and
> recompile Class1, it continues to print 12 until you recompile Class2.
Furthermore, the JLS also states:
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3>
> Inner classes may not declare static initializers (§8.7) or member interfaces.
Logical or not, the rules are laid out.

Signature
Lew
Mike Schilling - 10 Aug 2007 13:26 GMT
>> I have always wondered why static inner classes can have static
>> members but ordinary inner classes cannot. It seems a strange
[quoted text clipped - 22 lines]
> I suspect the choices matter at a low level in either the compiler or the
> JVM and would've been difficult.
I disagree. I've always considered the restriction arbitrary, and think the
behavior is both clear and easy to implement. There's already a model for
its behavior: a local or anonymous class defined inside a static method of
the containing class. The resulting rules are:
1. Static members of an inner class would be truly static, that is, scoped
to the class rather than to an enclosing instance, and could be referenced
as Foo.Bar.member.
2. There is no enclosing instance inside a static method; attempts to
access instance methods of the containing class would be illegal.
And this all falls naturally out of the implementation.
Adam Maass - 11 Aug 2007 06:31 GMT
>I have always wondered why static inner classes can have static
> members but ordinary inner classes cannot. It seems a strange
[quoted text clipped - 3 lines]
> Is there some difficulty in implementation? Is there some reason why
> stylistically the statics would be wicked?
As others have suggested, the problem lays in the "staticness" of the
construct:
class Outer{
class Inner {
static int member; // illegal
}
}
Is there a "member" per Outer instance (in which case, it should just be a
member of Outer, not stuck in Inner, scoping be damned), or is there just
one "member"?
Roedy Green - 14 Aug 2007 03:06 GMT
>Is there a "member" per Outer instance (in which case, it should just be a
>member of Outer, not stuck in Inner, scoping be damned), or is there just
>one "member"?
statics are always one per class.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Lasse Reichstein Nielsen - 13 Aug 2007 22:55 GMT
> I have always wondered why static inner classes can have static
> members but ordinary inner classes cannot. It seems a strange
> anti-orthogonality.
My guess is that it's for consistency with the idea that an inner
class (a non-static nested class) is not /one/ class, but one class
/per instance/ of the outer class.
Following that idea, everything you describe become necessary.
You cannot have a static field shared by all the inner classes,
since a static belongs to only one class[1].
/L
[1] ... although you could implement it by implementing statics on the
inner class as non-statics on instances of the outer class. THAT would
be hackery, though.

Signature
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Mike Schilling - 13 Aug 2007 22:56 GMT
>> I have always wondered why static inner classes can have static
>> members but ordinary inner classes cannot. It seems a strange
[quoted text clipped - 3 lines]
> class (a non-static nested class) is not /one/ class, but one class
> /per instance/ of the outer class.
If that idea had any support, I might agree with you.
Lasse Reichstein Nielsen - 14 Aug 2007 01:07 GMT
>>> I have always wondered why static inner classes can have static
>>> members but ordinary inner classes cannot. It seems a strange
[quoted text clipped - 5 lines]
>
> If that idea had any support, I might agree with you.
Heh. I wish I could find anybody but myself saying it ... but that
might be just me googleing for the way I would formulate it.
I found a two year old discussion here, where I said essentially
the same, to essentially the same question.
<URL:http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/29346
b15b8b3ac80/034bb32c24a0f75b?lnk=st&q=%22statics+in+inner+classes%22&rnum=3&hl=e
n#034bb32c24a0f75b>
and another one in August 2005 too ... at least I am consistent :)
<URL:http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/cc69f
69cabb66d34/2e0efe80921ddf57?lnk=st&q=%22Nested+Class+Language+Lawyers%22&rnum=1
&hl=en#2e0efe80921ddf57>
Maybe I have just believed this for so long that I thought everybody
else did too :)
It is consistent with everything in the design of inner classes, so it's
not like I have had it challenged.
Ah well. It was a good idea.
/L

Signature
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Mike Schilling - 14 Aug 2007 01:41 GMT
>>>> I have always wondered why static inner classes can have static
>>>> members but ordinary inner classes cannot. It seems a strange
[quoted text clipped - 20 lines]
>
> Ah well. It was a good idea.
I was being snippy, and I apologize for that.
Anyway, we had this discussion back in February starting with this post:
http://groups.google.com/group/comp.lang.java.programmer/msg/ff5c4bf25469be1a
and the consensus, I think, was that while some language in the JLS suggests
that there's an inner class per instance of the outer class, that the idea
can't be sustained.
Roedy Green - 14 Aug 2007 03:02 GMT
>My guess is that it's for consistency with the idea that an inner
>class (a non-static nested class) is not /one/ class, but one class
>/per instance/ of the outer class.
There may be many instances, but only one inner class. Have a look at
the generated class files. There is only one per inner class,
instance or static, not one per instance of the outer class.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com