static
, there exists exactly one incarnation of the field, no
matter how many instances (possibly zero) of the class may eventually be created.
A static
field, sometimes called a class variable, is incarnated when the class is
initialized (§12.4).
A field that is not declared static
(sometimes called a non-static
field) is called an instance variable. Whenever a new instance of a class is created, a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.
class Point { int x, y, useCount; Point(int x, int y) { this.x = x; this.y = y; } final static Point origin = new Point(0, 0); }prints:
class Test { public static void main(String[] args) { Point p = new Point(1,1); Point q = new Point(2,2); p.x = 3; p.y = 3; p.useCount++; p.origin.useCount++; System.out.println("(" + q.x + "," + q.y + ")"); System.out.println(q.useCount); System.out.println(q.origin == Point.origin); System.out.println(q.origin.useCount); } }
(2,2) 0 true 1showing that changing the fields
x
, y
, and useCount
of p
does not affect the fields
of q
, because these fields are instance variables in distinct objects. In this example,
the class variable origin
of the class Point
is referenced both using the class
name as a qualifier, in Point.origin
, and using variables of the class type in
field access expressions (§15.10), as in p.origin
and q.origin
. These two ways
of accessing the origin
class variable access the same object, evidenced by the
fact that the value of the reference equality expression (§15.20.3):
q.origin==Point.origin
is true
. Further evidence is that the incrementation:
p.origin.useCount++;causes the value of q.origin.useCount to be
1
; this is so because p.origin
and
q.origin
refer to the same variable.
static
Fieldsprivate
was not declared static
and is changed to
be declared static
, or vice versa, then a linkage time error, specifically an
IncompatibleClassChangeError
, will result if the field is used by a preexisting
binary which expected a field of the other kind. Such changes are not recommended in code that has been widely distributed.
static
is called a class method. A class method is
always invoked without reference to a particular object. An attempt to reference
the current object using the keyword this
or the keyword super
in the body of a
class method results in a compile time error. It is a compile-time error for a
static
method to be declared abstract
.
A method that is not declared static
is called an instance method, and sometimes called a non-static
method). An instance method is always invoked with respect to an object, which becomes the current object to which the keywords this
and super
refer during execution of the method body.
static
Methodsprivate
was declared static
(that is, a class
method) and is changed to not be declared static
(that is, to an instance method),
or vice versa, then compatibility with pre-existing binaries may be broken, resulting in a linkage time error, namely an IncompatibleClassChangeError
, if these
methods are used by the pre-existing binaries. Such changes are not recommended
in code that has been widely distributed.
StaticInitializer:It is a compile-time error for a static initializer to be able to complete abruptly (§14.1, §15.5) with a checked exception (§11.2).
static
Block
The static initializers and class variable initializers are executed in textual order and may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope. This restriction is designed to catch, at compile time, circular or otherwise malformed initializations. Thus, both:
class Z { static int i = j + 2; static int j = 4; }and:
class Z { static { i = j + 2; } static int i, j; static { j = 4; } }result in compile-time errors.
Accesses to class variables by methods are not checked in this way, so:
class Z { static int peek() { return j; }produces the output:
static int i = peek(); static int j = 1; }
class Test { public static void main(String[] args) { System.out.println(Z.i); }
}
0because the variable initializer for
i
uses the class method peek
to access the
value of the variable j
before j
has been initialized by its variable initializer, at
which point it still has its default value (§4.5.4).
If a return
statement (§14.15) appears anywhere within a static initializer, then a compile-time error occurs.
If the keyword this
(§15.7.2) or the keyword super
(§15.10, §15.11) appears anywhere within a static initializer, then a compile-time error occurs.