Contents | Prev | Next | Index

CHAPTER 16

Definite Assignment


Each local variable must have a definitely assigned value when any access of its value occurs. An access to its value consists of the simple name of the variable occurring anywhere in an expression except as the left-hand operand of the simple assignment operator =.

A Java compiler must carry out a specific conservative flow analysis to make sure that, for every access of a local variable, the local variable is definitely assigned before the access; otherwise a compile-time error must occur.

The remainder of this chapter is devoted to a precise explanation of the words "definitely assigned before". The idea is that an assignment to the local variable must occur on every possible execution path to the access from the beginning of the constructor, method, or static initializer that contains the access. The analysis takes into account the structure of statements and expressions; it also provides a special treatment of the expression operators !, &&, ||, and ? :, the operators &, |, ^, ==, and != with boolean operands, and boolean-valued constant expressions. For example, a Java compiler recognizes that k is definitely assigned before its access (as an argument of a method invocation) in the code:


{
	int k;
	if (v > 0 && (k = System.in.read()) >= 0)
		System.out.println(k);
}
because the access occurs only if the value of the expression:

v > 0 && (k = System.in.read()) >= 0
is true, and the value can be true only if the assignment to k is executed (more properly, evaluated). Similarly, a Java compiler will recognize that in the code:


{
	int k;
	while (true) {
		k = n;
		if (k >= 5) break;
		n = 6;
	}
	System.out.println(k);
}
the variable k is definitely assigned by the while statement because the condition expression true never has the value false, so only the break statement can cause the while statement to complete normally, and k is definitely assigned before the break statement.

Except for the special treatment of certain boolean operators and of boolean-valued constant expressions, the values of expressions are not taken into account in the flow analysis. For example, a Java compiler must produce a compile-time error for the code:


{
	int k;
	int n = 5;
	if (n > 2)
		k = 3;
	System.out.println(k);					// k is not "definitely assigned" before this
}
even though the value of n is known at compile time, and in principle it can be known at compile time that the assignment to k will always be executed (more properly, evaluated). A Java compiler must operate according to the rules laid out in this section. The rules recognize only constant expressions; in this example, the expression n > 2 is not a constant expression as defined in §15.27.

As another example, a Java compiler will accept the code:


void flow(boolean flag) {
	int k;
	if (flag)
		k = 3;
	else
		k = 4;
	System.out.println(k);
}
as far as definite assignment of k is concerned, because the rules outlined in this section allow it to tell that k is assigned no matter whether the flag is true or false. But the rules do not accept the variation:


void flow(boolean flag) {
	int k;
	if (flag)
		k = 3;
	if (!flag)
		k = 4;
	System.out.println(k); 					// k is not "definitely assigned" before here
}
and so compiling this program must cause a compile-time error to occur.

In order to precisely specify all the cases of definite assignment, the rules in this section define two technical terms:

In order to specify boolean-valued expressions, the latter notion is refined into two cases:

Here when true and when false refer to the value of the expression. For example, the local variable k is definitely assigned a value after evaluation of the expression

a && ((k=m) > 5)
when the expression is true but not when the expression is false (because if a is false, then the assignment to k is not executed (more properly, evaluated)).

The statement "V is definitely assigned after X" (where V is a local variable and X is a statement or expression) means "V is definitely assigned after X if X completes normally". If X completes abruptly, the assignment may not have occurred, and the rules stated here take this into account. A peculiar consequence of this definition is that "V is definitely assigned after break;" is always true! Because a break statement never completes normally, it is vacuously true that V has been assigned a value if the break statement completes normally.

To shorten the rules, the customary abbreviation "iff" is used to mean "if and only if".

Let V be a local variable. Let a, b, c, and e be expressions. Let S and T be statements.

16.1 Definite Assignment and Expressions

16.1.1 Boolean Constant Expressions

V is definitely assigned after any constant expression whose value is true when false. V is definitely assigned after any constant expression whose value is false when true.

A constant expression whose value is true never has the value false, and a constant expression whose value is false never has the value true, these definitions are vacuously satisfied. They are helpful in analyzing expressions involving the boolean operators &&, ||, and ! (§16.1.3, §16.1.4, §16.1.5).

16.1.2 Boolean-valued Expressions

For every boolean-valued expression:

16.1.3 The Boolean Operator &&

16.1.4 The Boolean Operator ||

16.1.5 The Boolean Operator !

16.1.6 The Boolean Operator &

16.1.7 The Boolean Operator |

16.1.8 The Boolean Operator ^

16.1.9 The Boolean Operator ==

16.1.10 The Boolean Operator !=

The rules for a != b are identical to the rules for a ^ b (§16.1.8).

16.1.11 The Boolean Operator ? :

Suppose that b and c are boolean-valued expressions.

16.1.12 The Conditional Operator ? :

Suppose that b and c are expressions that are not boolean-valued.

16.1.13 Boolean Assignment Expressions

Suppose that an assignment expression a = b, a &= b, a |= b, or a ^= b is boolean- valued.

Note that if a is V and V is not definitely assigned before a compound assignment such as a &= b, then a compile-time error will necessarily occur. The rules stated above include the disjunct "a is V" so that V will be considered to have been definitely assigned at later points in the code. Including the disjunct "a is V" does not affect the binary decision as to whether a program is acceptable or will result in a compile-time error, but it affects how many different points in the code may be regarded as erroneous, and so in practice it can improve the quality of error reporting.

16.1.14 Other Assignment Expressions

Suppose that an assignment expression a = b, a += b, a -= b, a *= b, a /= b, a %= b, a <<= b, a >>= b, a >>>= b, a &= b, a |= b, or a ^= b is not boolean-valued.

16.1.15 Operators ++ and --

16.1.16 Other Expressions

If an expression is not boolean-valued and is not a conditional-operator expression or assignment expression, the following rules apply:

For any immediate subexpression y of an expression x, V is definitely assigned before y iff V is definitely assigned before x or one of the following situations is true:

16.2 Definite Assignment and Statements

16.2.1 Empty Statements

16.2.2 Blocks

16.2.3 Local Variable Declaration Statements

16.2.4 Labeled Statements

16.2.5 Expression Statements

16.2.6 if Statements

16.2.7 switch Statements

16.2.8 while Statements

16.2.9 do Statements

16.2.10 for Statements

16.2.10.1 Initialization Part

16.2.10.2 Incrementation Part

16.2.11 break, continue, return, and throw Statements

16.2.12 synchronized Statements

16.2.13 try Statements

V is definitely assigned before a finally block iff V is definitely assigned before the try statement.


Contents | Prev | Next | Index

Java Language Specification (HTML generated by Suzette Pelouch on February 24, 1998)
Copyright © 1996 Sun Microsystems, Inc. All rights reserved
Please send any comments or corrections to doug.kramer@sun.com