Question on static classes

I

Ian Semmel

Suppose I have

public class MyClass
{
...
private static class InnerClass extends SystemClass
{
int i;
public InnerClass (int i)
{
this.i = i;
}
..
}

public static SystemClass GetInner ( int i)
{
return new InnerClass (i);
}
}

Does this work OK ?

SystemClass s1 = MyClass.GetInner(1);
SystemClass s2 = MyClass.GetInner(2);

That is, does the fact that the class is static mean that there is only one instance of InnerClass ?
 
M

Mike Schilling

Ian said:
Suppose I have

public class MyClass
{
...
private static class InnerClass extends SystemClass
{
int i;
public InnerClass (int i)
{
this.i = i;
}
..
}

public static SystemClass GetInner ( int i)
{
return new InnerClass (i);
}
}

Does this work OK ?

SystemClass s1 = MyClass.GetInner(1);
SystemClass s2 = MyClass.GetInner(2);
Yes.


That is, does the fact that the class is static mean that there is
only one instance of InnerClass ?

No. What "static" means is that an instance of InnerClass does not have a
"containing instance" of MyClass. (In fact, it makes "InnerClass" a
misleading name; "NestedClass" would be preferable.) That is, given

MyClass
{
public void doit(){ .....}
...
}

It would not be legal to write

s1.doit();

because there's no instance MyClass associated with s1 on which doit() would
be called.
 
T

Tom Anderson

Suppose I have

public class MyClass
{
...
private static class InnerClass extends SystemClass
{
int i;
public InnerClass (int i)
{
this.i = i;
}
..
}

public static SystemClass GetInner ( int i)
{
return new InnerClass (i);
}
}

SystemClass s1 = MyClass.GetInner(1);
SystemClass s2 = MyClass.GetInner(2);

Does this work OK ?

What you've written is basically exactly the same as if InnerClass was a
top-level class. When you have static inner classes (nested classes, Mike
and Mark inform me they're called), the innerness is purely a naming
convention - it doesn't have any impact in terms of the relation of
different objects. You could write the same code with everything as
top-level classes and it would be the same. Well, apart from access issues
- a nested class can see private static fields that are invisible from a
separate top-level class.

tom
 
M

Mike Schilling

Tom said:
What you've written is basically exactly the same as if InnerClass
was a top-level class. When you have static inner classes (nested
classes, Mike and Mark inform me they're called), the innerness is
purely a naming convention - it doesn't have any impact in terms of
the relation of different objects. You could write the same code with
everything as top-level classes and it would be the same. Well, apart
from access issues - a nested class can see private static fields
that are invisible from a separate top-level class.

It can see everything private: both instance and static, both fields and
methods, e.g.

class Outer
{
private static int s_field;
private static int s_method(int i);
private int field;
private int method(int i);

static class Inner
{
void m(Outer o)
{
o.field = o.s_method(o.method(o.s_field));
}
}
}


is all legal.
 
M

Mark Space

Tom Anderson wrote:
?
What you've written is basically exactly the same as if InnerClass was a
top-level class. When you have static inner classes (nested classes,
Mike and Mark inform me they're called), the innerness is purely a

Yes, check that link I posted.

+-------------------+
| Nested Class |
+-------------------+
/ \
+---------------+ +------------------------+
| Inner Class | | Static Nested Class |
+---------------+ +------------------------+
/ \
+--------+ +-------------+
| Local | | Anonymous |
| Class | | Class |
+--------+ +-------------+



Static Nested and Inner classes are disjoint concepts.
naming convention - it doesn't have any impact in terms of the relation
of different objects. You could write the same code with everything as
top-level classes and it would be the same. Well, apart from access
issues - a nested class can see private static fields that are invisible
from a separate top-level class.

One difference is you can't make top level private classes:

public class Useful {}
private class Helper {} // Error


However, you can make static classes private, and since they function as
top level classes, you get the same effect.

public class Useful {
// ...
private static class Helper {}
}

As you say, this also allows Helper to see private members of Useful, a
bit like C++ "friend" keyword. Which is probably what you want.

I have not tried this: it makes sense however that Helper can see all
private members of Useful, static and instance. However, Helper cannot
access instance members with out an instance of Useful. (I'm trying to
understand this better myself, any additional insights?)
 
M

Mike Schilling

Mark said:
Tom Anderson wrote:
?

Yes, check that link I posted.

+-------------------+
| Nested Class |
+-------------------+
/ \
+---------------+ +------------------------+
| Inner Class | | Static Nested Class |
+---------------+ +------------------------+
/ \
+--------+ +-------------+
| Local | | Anonymous |
| Class | | Class |
+--------+ +-------------+

This is Sun's standard explanation of the terms, but I dislike it, since
there are really two orthoganol concepts:

1. Whether there's a containing instance
2. The scope at which the class is defined.

Local and anonymous classes defined inside static methods are also "static",
in that they lack a containing instance, but this diagram ignores that.
 
M

Mark Space

Mike said:
Local and anonymous classes defined inside static methods are also "static",
in that they lack a containing instance, but this diagram ignores that.

So you're saying there are also local static nested classes and
anonymous static nested classes in addition to local inner classes and
anonymous inner classes. Makes sense.

I like the term inner because it clearly says that there's a containing
instance. One instance is is "inside" another instance.

I think "static nested" is kinda clumsy to say though. I guess since
you can't make a top-level class static, that only leaves nested
classes, so you can abbreviate those terms to static class, static
local, and static anonymous with the "nested" being implied.
 
L

Lew

Mike said:
So you're saying there are also local static nested classes and
anonymous static nested classes in addition to local inner classes and
anonymous inner classes.  Makes sense.

That's not right. Anonymous and local classes are not static nested
classes.

The JLS says:
An inner class is a nested class that is not explicitly or implicitly declared static.
and

An instance of an inner class I whose declaration occurs in a static context
has no lexically enclosing instances. However, if I is immediately declared
within a static method or static initializer then I does have an enclosing
block, which is the innermost block statement lexically enclosing the
declaration of I.
and

Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member
classes (§8.5).

A local or anonymous class declared in a static context is still an
inner class, not a static one, just an inner class with no lexically
enclosing instance. As such it cannot declare non-constant static
members or do other things forbidden to inner classes but permitted to
static nested classes.

The JLS refers to "inner classes whose declarations do not occur in a
static context" versus "an inner class ... whose declaration occurs in
a static context". Neither one is a static nested class.
 
M

Mike Schilling

Lew said:
[The JLS says]
Inner classes include local (§14.3), anonymous (§15.9.5) and non-static
member
classes (§8.5)

Yes, it does. There are six types of non-top-level classes, since there are
three levels at which they can be defined:

1. As a child of a class
2. As a child of a method
3. In method code

and they can either

A. have a containing object, or
B. have no containing object

and all six combinations are possible.

The JLS says that 1A, 2A, 2B, 3A, and 3B are "inner classes" but 1B is not.
This is stupid.
 
T

Tom Anderson

It can see everything private: both instance and static

Ah, i didn't know that.

The access rules are one of the things i still find confusing after all
these years. I remember the day that i realised that instance methods
could see private fields of instances of their defining class *other* than
'this' - i was shocked! I still never remember that 'protected' members
are accessible to any class in the same package, as well as subclasses.

tom
 
M

Mark Space

Mike said:
Yes, it does. There are six types of non-top-level classes, since there are
three levels at which they can be defined:

1. As a child of a class
2. As a child of a method
3. In method code

Don't forget "static initializer" which doesn't seem to be to be able to
ever have a containing object.

The JLS says that 1A, 2A, 2B, 3A, and 3B are "inner classes" but 1B is not.
This is stupid.

I agree, trying to keep them all straight is a darn mess. Some more
names and explicit terminology would help.
 
M

Mike Schilling

Mark said:
Don't forget "static initializer" which doesn't seem to be to be able
to ever have a containing object.

Good point; for this purpose, take initializer as a special case of method.
 
M

Mike Schilling

Lew said:
Mike said:
Lew said:
[The JLS says]
Inner classes include local (?14.3), anonymous (?15.9.5) and
non-static member
classes (?8.5)

Yes, it does. There are six types of non-top-level classes, since
there are three levels at which they can be defined:

1. As a child of a class
2. As a child of a method
3. In method code

and they can either

A. have a containing object, or
B. have no containing object

and all six combinations are possible.

The JLS says that 1A, 2A, 2B, 3A, and 3B are "inner classes" but 1B
is not.

Again, that is not correct. The JLS calls a member class declared
with the keyword "static" not an inner class.

Right. That's 1B.
The fact that it does
not have a containing instance is a consequence of that, not the
defining characteristic.

That's what the static keyword means there: that there is no containing
instance. It doesn't have any other effect.
Perhaps the stupidity comes from one's use of the wrong definition of
"inner class", not from the correct definition.

Nope. But thanks for playing.
 
I

Ian Semmel

Ian said:
Suppose I have

public class MyClass
{
...
private static class InnerClass extends SystemClass
{
int i;
public InnerClass (int i)
{
this.i = i;
}
..
}

public static SystemClass GetInner ( int i)
{
return new InnerClass (i);
}
}

Does this work OK ?

SystemClass s1 = MyClass.GetInner(1);
SystemClass s2 = MyClass.GetInner(2);

That is, does the fact that the class is static mean that there is only
one instance of InnerClass ?

Thank you all for the very informative discussion (which I started out understanding but it then got a bit deep for me).

The main thing I discovered is that what I am doing is what I want.
 
R

Roedy Green

That is, does the fact that the class is static mean that there is only one instance of InnerClass ?

see http://mindprod.com/jgloss/nestedclasses.html

Mr. Gosling should be considered an ESL student. In order to reduce
the number of keywords he was willing to misuse English words in ways
that make a lexicographer grind their teeth.

He uses he word "static" the way a valley girl might use the word
"thing". Don't take it literally. Almost never does static have
anything to do with "not dynamic".

In this case it means "does not require an associated instance of the
outer class." go figure how hell he twisted "static" to mean that!

You can allocate all the instances of a static class you want. That
sounds nuts doesn't it. You'd think a static class could not be
instantiated at all!
 
L

Lew

Roedy said:
You can allocate all the instances of a static class you want.  That
sounds nuts doesn't it.  You'd think a static class could not be
instantiated at all!

You wouldn't think that if you let the JLS define its terms instead of
trying to apply definitions that aren't relevant.
 
L

Lew

Eric said:
     McKean's Law strikes again.

If you're referring to the use of the word "their" as a gender-neutral
singular possessive, that has over 500 years' worth of erudite usage
on both sides of the Pond to justify it. While controversial, the use
of "they/them/their" as a singular gender-neutral pronoun has a long-
time and vocal following. It also has the virtue of widespread common
usage and lacks the awkwardness of "his or her", etc. Those who
consider it "improper" are just pedantic nellies who are out of touch
with the actual language.

If you're referring to the lack of a comma after "keywords" then it's
a point well taken.
 
M

Mike Schilling

Lew said:
You wouldn't think that if you let the JLS define its terms instead
of
trying to apply definitions that aren't relevant.

In C, "static" meant just that: allocated statically.

In C++, Stroustrup needed a term to express per-class (as opposed to
per-instance), and used "static" since it was already a keyword and
meant more or less the right thing for fields. This gave static has
the additional meaning of "not per-instance".

In Java (and note that this was Java 1.2, so introducing a new keyword
had compatibility issues), a term was needed for "nested class that
isn't tied to an instance". Yet again, "static" already had this
meaning more or less.

I might be able to get indignant about this if it weren't the same way
that natural languages evolve.
 
T

Tom Anderson

In C, "static" meant just that: allocated statically.

In C++, Stroustrup needed a term to express per-class (as opposed to
per-instance), and used "static" since it was already a keyword and
meant more or less the right thing for fields. This gave static has
the additional meaning of "not per-instance".

In Java (and note that this was Java 1.2, so introducing a new keyword
had compatibility issues), a term was needed for "nested class that
isn't tied to an instance". Yet again, "static" already had this
meaning more or less.

I might be able to get indignant about this if it weren't the same way
that natural languages evolve.

And also, because it means we can blame Stroustrup for it,

AGAIN.

tom
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,588
Members
45,099
Latest member
AmbrosePri
Top