Local Variable Declarations are statements that introduce new variables to the block that contains them. Local Variable Declarations can possess modifiers that apply to the variables, and optionally, an initializer for each variable declared.
Variables declared in a Local Variable Declaration are declared (and possibly initialized) in the order they're written.
Local Variable Declarations can be expressed through:
1 | modifiers type first-var-decl
additional-var-decls ; |
where...
modifiers | is either:
|
||||||
type | is any type that can be used to declare a variable (i.e., that is
not void ).
|
||||||
first-var-decl | is an unused variable identifier, then any number of (optionally
annotated) pairs of brackets ([] ) indicating additional
array dimensions, then optionally followed by an equals token (= )
and an expression whose type is that of the variable. Equivalently,
the first-var-decl has the form:
name array-dims
= init-expr
where...
|
||||||
additional-var-decls | is any number of first-var-decls,
separated by comma tokens (, ).
|
Local variable declarations are the basic way to introduce a new variable to a local scope (called, a local variable). Such variables exist and are accessible immediately after their declaration (even within the same local variable declaration; see below), within the scope in which they were declared.
They can be used within any local scope, such as inside static and instance initializers and method bodies.
Local variables can be read and evaluated only after they have been
definitively assigned a value (see Definite Assignment). If there is a path of execution
(even a single path) that would result in the variable not being
initialized by the time it is read, the read is not valid. For example,
in the following code, each commented print statement illegally refers
to x
:
int x;
// System.out.println(x); // x not yet initialized; error
if (Math.random() > .25) {
// System.out.println(x); // x not yet initialized; error
x = 20;
System.out.println(x); // x has been initialized; prints 20
}
// System.out.println(x); // x not yet initialized; error
final
local variable declarations create a final
local variable. In contrast to final
fields (class
members), they do not have to be given a value (if they are not ever
read). Once they have been assigned a value, though, they cannot be
reassigned (similar to final
fields).
final
local variables can only be assigned a value once.
It's a compile-time error for any path of execution to assign to a final
variable more than once.
The variable introduced by a local variable declaration can be constant if all of the following are true:
final
(i.e. final
is present in the list of modifiers),
String
or some primitive
type,
=
init-expr),
and
int x, y, z = x = y = 10; // Initializes all 3 variables to 10.
System.out.println(x + y + z); // All variables are accessible and initialized; prints 30.
In the above code, x
and y
are accessible
within the initializer expression of z
, and can be
assigned values before the end of the statement.
Comparatively, declared local variables cannot be accessed or used before their declaration, even within the same statement:
int x = y, y = 10; // Compiler error: cannot find symbol 'y'
int x = 0;
int y = ++x, z = ++x, w = ++x; // Initializes x, y, and z to 1, 2, and 3, respectively.
// x is set to 3.
System.out.println("x: " + x);
System.out.println("y: " + y + ", z: " + z + ", w: " + w);
This code prints:x: 3
y: 1, z: 2, w: 3
final int x;
if (Math.random() < .5) {
x = 10;
System.out.println(x);
} else {
// System.out.println(x); // x cannot be accessed here.
}
// System.out.println(x); // x cannot be accessed here because it may not have been initialized
final long x = 10;
byte b = x;
This code compiles because x
is a
constant variable, meaning that its evaluation when initializing b
is performed at compile-time. Since b
is initialized with
an integral constant-expression whose value (10
) is known
to be able to fit within the byte
type, the assignment
succeeds.
If x
's local variable declaration were not declared
constant, the variable x
would not be a constant
variable. This would cause the evaluation of x
, within b
's
initializer, to not undergo value-checks that determine if the value
of b
's initializer can fit into b
, making
the initialization result in the standard loss-of-precision in
assignment error.