Stefan said:
class A
{ static int x = 0;
static void f(){}
static class B{} }
different wording might be needed to explain the meaning of
each »static«.
Not really. In all three cases, static means the thing is associated
with the class A but not with specific instances of A.
In the int's case lack of "static" would mean that each instance has a
separate value for x; in the method's case that the method must be
invoked on a specific instance of A and acts on that instance; and in
the nested class's case that an instance of the nested class is
associated with a specific instance of A (making it an "inner" class).
So the details of how it's associated with a specific instance vary, but
they all have in common that they are associated with a specific instance.
Static, on the other hand, just means none of them are associated with a
specific instance of A. Instances of B aren't; f is basically a function
rather than a method; x is a global; all are scoped by A (and f and
methods of B can see private members of A).
It's more that non-static is a bit different in each case, really.
Usually, lifetime and dynamic concepts (like recursion)
are more difficult to grasp than static scoping.
The simple meaning of static scoping is basically "there's only one".
Although with the nested class B above, there's technically only one
whether or not it's static, it can be thought of as having a "copy" for
each instance of A if it's not in a certain sense. You could
conceptualize this as an anonymous subclass, so that they are all
assignable to any reference of type B regardless of which instance of A
they are attached to. Although it's not implemented that way under the
hood, I don't think, and reflection will only ever show you a single
class B and no subclasses you don't explicitly make (barring arcane and
unusual multiple-classloader use anyway).
But basically that's it. All are associated with the class A as regards
lexical scoping and having access to A's private parts. The non-statics
are used in connection with instances of A and may vary in behavior
modulo which instance. The statics are not and may not, and referencing
them through specific instances just aliases them. When used they are
associated only with the class A and not any specific instance, however
they were accessed. Of course this means that the static method f()
cannot be polymorphic either, since only an instance could have a more
specific run-time type, and f() (even when accessed via an instance of
A, a.f()) when used does not behave in a way associated with a specific
instance (that might have been of a subclass of A).
In practise, the subtleties (particularly f()'s non-polymorphic nature
and the nested/inner class behaviors) make it necessary to give details
specific to the cases of methods and nested classes. But it's really the
non-static ones that have the exceptional behavior -- usage only in
association with a specific instance of A, polymorphism in the case of
methods, etc.