I could not understand why nsmc, local classes or anonymous classes
cannot have static members ?
Can some throw light on that ?
Thanks,
Ankur
Anonymous classes can not have static methods because those
can not be called by anyone.
I don't know what you mean by nsmc and local classes.
Arne
Well, I don't know, but I'll hazard a guess or two:
1. Conceptually, non-static member classes, local and anonymous classes
are all "a part of" the enclosing class. Thus they "should" be using
the enclosing class for any static members.
2. For future potential optimization, preventing static members might
allow future JVMs to take some short cuts with inner class objects, and
initialize the objects more quickly or otherwise do away with one or
more steps involved in creating their class object. Since static
members weren't needed (see 1), they were proscribed.
By nsmc I mean non static member classes.
By local classes I mean classes declared in local blocks.
Rit
Thanks for your response. Local classes in static context do no have
an enclosing object. What could happen if nsmc, local classes or
anonymous classes had static members. Why can't Local classes in
static context have static members at least ?
Rit
Ah.
Somebody made a decision.
Given that such classes are tied to something non-static (the
instance of the surrounding class), then the use of static would
be bit fuzzy in semantics.
> By local classes I mean classes declared in local blocks.
Forgot about those bastards.
I think they are mostly a certification thingy. I don't think I
have ever seen real world code using it.
Same applies as above.
Arne
I believe the other respondents have already addressed this. I'll add that
since inner classes are inner classes are inner classes, it saves a lot of
complexity not to have different rules for them when they're in a static context.
Another consideration is to think through what a (non-constant) static member
would signify for an inner or local class. What does "class-wide scope" even
mean there? The scope is local to begin with, so adding class-wide scope to a
local-scoped construct is dicey at best.
If one has a need to refer to a class widely, it should be neither local nor
inner with an enclosing instance anyway, ergo the utility of a static member
is nil. If you need a static member, declare a top-level class or static
nested class to hold it. If you need it in a local/inner class, put it in the
enclosing class. Having it in the inner class adds negligible value to the
language, and would require complexity to implement. The cost-benefit
analysis doesn't justify it. We may never know what the Founding Designers
thought about the issue, but we can guess that they felt much the same.
Given that the language prohibits static (non-constant) members in an inner
class, and the workarounds are simple and straightforward, I'd rate the reason
behind the decision as not very critical. I know that I find types much
easier to reason about with the restriction against static members of local or
inner classes than I would without it, so I am glad they chose as they did.
--
Lew
> On 12-12-2009 17:15, Rit wrote:
>> By local classes I mean classes declared in local blocks.
> I think they are mostly a certification thingy. I don't think I
> have ever seen real world code using it.
Except of course for anonymous local classes, which I'm sure you've seen
quite a few of. ;)
>
> Thanks for your response. Local classes in static context do no have
> an enclosing object. What could happen if nsmc, local classes or
> anonymous classes had static members. Why can't Local classes in
> static context have static members at least ?
I didn't look this up but: I'm pretty sure that while you are correct
that local classes in a static context have no enclosing *object* they
do have an enclosing *class*. That's what I'm referring to, the class
object itself. Not an instantiation of said class object.
Even local classes in a static context have an outer, enclosing class
which can be used for any needed static members, like constants or methods.
>
>I could not understand why nsmc, local classes or anonymous classes
>cannot have static members ?
>
>Can some throw light on that ?
Inner classes are not permitted to have static methods or fields. That
is not quite true. They are allowed static final compile time
constants, which are treated as if there were literals. Sorry I don�t
know why the restriction. Nobody I have asked knows why. This is
probably the single most annoying fact about nested classes. If inner
classes need statics, they have to get the outer class to hold them,
or you have to use static nested classes or you have to inherit the
static fields. Oddly, inner classes are permitted to extend classes
that do have static methods and fields.
see http://mindprod.com/jgloss/nestedclasses.html
--
Roedy Green Canadian Mind Products
http://mindprod.com
The future has already happened, it just isn�t evenly distributed.
~ William Gibson (born: 1948-03-17 age: 61)
>
>Anonymous classes can not have static methods because those
>can not be called by anyone.
You could not call them from outside, since they would not have a
name, but why could you not call such static methods within the
anonymous class?
My guess is that the objective is to allow the more light weight classes
to be effectively unloaded without affecting anything.
Patricia
That's not so odd considering that static members aren't really inherited,
just accessible.
--
Lew
I have seen plenty of anonymous classes.
Traditionally they are not considered to be local classes.
Arne
I guess you could do that.
But then what benefits would that static method provide
that a similar non-static method would not provide?
Arne
>I guess you could do that.
>
>But then what benefits would that static method provide
>that a similar non-static method would not provide?
same thing a normal static method does: single copy of variable
common to all instances, persistence, ability to count instances.
Roedy Green wrote:
> same thing a normal static method does: single copy of variable
> common to all instances, persistence, ability to count instances.
>
Let's see. If it's a local class without an enclosing instance (e.g.,
in a static context), there will not be more instances than are
declared in that invocation of the context. A variable can be shared
by making it a final variable in the context outside the local class.
Counting the instances will be useless.
If it's an inner class with an enclosing instance, do you want the
static member shared across all enclosing instances or only among
invocations within the same enclosing instance? How "static" should
'static' be?
It just doesn't make sense to have static members in inner classes.
--
Lew
No, it wouldn't. You can dicuss it all you like, but it's quite clear that
the only sensible decision is one copy of each static per Class instance.
(It might be fuzzy if the msmc and its parent class could be loaded by
different classloaders, but that's not possible.)
I am not sure that I would call that sensible.
It is not exactly "classic static behavior".
Arne
But the static method can not be called from a static context,
so whatever it does could be achieved by making it non static.
And regarding counting instances, then look at what Mike Schilling
considers sensible.
Arne
It seems to me that it is. "static" means "one per Class". not "one
per instance".
Perhaps I wasn't clear, becasue what I'm thinking counts instances
quite well, e.g.
class Outer
{
class Inner
{
static int count;
Inner()
{
count++;
}
}
}
"count" willl give the number of Inner.Outer instances ever created,
regardless of the value of the enclosing Inner instance. Though in
fact what I've usually wanted a static method for is when Inner needs
a cache, e.g.
class Outer
{
class Inner
{
static Map<String, Schema>schemas = new HashMap<String,
Schema>();
private Schema schema;
Inner(String namespace)
{
synchronized(schemas)
{
schema = schemas.get(namespace);
if (schema == null)
{
schema = loadSchema(namespace);
schemas.put(namespace, schema);
}
}
}
}
}
Again, I want to use the same cache regardless of the value of the
enclosing instance.
This is quite attainable without changing the rules, natch. While some seem
to prefer the syntax of the 'static' member being within the inner class,
there's no real disadvantage to the currently-legal idiom. We just have to
adapt our esthetic to The Way It Is in Java, and chalk it up as yet another
thing we'd have done better were it up to us, accepting that we can at least
achieve the functional equivalent if not through the means we imagine we'd
prefer. Oh, well.
> regardless of the value of the enclosing Inner instance. Though in
> fact what I've usually wanted a static method for is when Inner needs
> a cache, e.g.
>
> class Outer
> {
> class Inner
> {
> static Map<String, Schema>schemas = new HashMap<String,
> Schema>();
> private Schema schema;
>
> Inner(String namespace)
> {
> synchronized(schemas)
> {
> schema = schemas.get(namespace);
> if (schema == null)
> {
> schema = loadSchema(namespace);
> schemas.put(namespace, schema);
> }
> }
> }
> }
> }
>
> Again, I want to use the same cache regardless of the value of the
> enclosing instance.
Again, you can do that with currently-legal syntax, just not the exact way you
suggest. Oh, well.
--
Lew
OK. I misunderstood what you wanted then. That is sensible
and consistent.
Arne
True. The only downside is that it doesn't represent scoping
correctly.