Movatterモバイル変換


[0]ホーム

URL:


Oracle Logo

Java SE >Java SE Specifications >Java Language Specification

Chapter 16. Definite Assignment
Prev   Next

Chapter 16. Definite Assignment

Table of Contents

16.1. Definite Assignment and Expressions
16.1.1. Boolean Constant Expressions
16.1.2. Conditional-And Operator&&
16.1.3. Conditional-Or Operator||
16.1.4. Logical Complement Operator!
16.1.5. Conditional Operator? :
16.1.6. Conditional Operator? :
16.1.7. Other Expressions of Typeboolean
16.1.8. Assignment Expressions
16.1.9. Operators++ and--
16.1.10. Other Expressions
16.2. Definite Assignment and Statements
16.2.1. Empty Statements
16.2.2. Blocks
16.2.3. Local Class Declaration Statements
16.2.4. Local Variable Declaration Statements
16.2.5. Labeled Statements
16.2.6. Expression Statements
16.2.7.if Statements
16.2.8.assert Statements
16.2.9.switch Statements
16.2.10.while Statements
16.2.11.do Statements
16.2.12.for Statements
16.2.12.1. Initialization Part offor Statement
16.2.12.2. Incrementation Part offor Statement
16.2.13.break,continue,return, andthrow Statements
16.2.14.synchronized Statements
16.2.15.try Statements
16.3. Definite Assignment and Parameters
16.4. Definite Assignment and Array Initializers
16.5. Definite Assignment and Enum Constants
16.6. Definite Assignment and Anonymous Classes
16.7. Definite Assignment and Member Types
16.8. Definite Assignment and Static Initializers
16.9. Definite Assignment, Constructors, and Instance Initializers

Each local variable (§14.4) and every blankfinal field (§4.12.4,§8.3.1.2) must have adefinitely assigned value when any access of its value occurs.

An access to its value consists of the simple name of the variable (or, for a field, the simple name of the field qualified bythis) occurring anywhere in an expression except as the left-hand operand of the simple assignment operator= (§15.26.1).

For every access of a local variable or blankfinal fieldx,x must be definitely assigned before the access, or a compile-time error occurs.

Similarly, every blankfinal variable must be assigned at most once; it must bedefinitely unassigned when an assignment to it occurs.

Such an assignment is defined to occur if and only if either the simple name of the variable (or, for a field, its simple name qualified bythis) occurs on the left hand side of an assignment operator.

For every assignment to a blankfinal variable, the variable must be definitely unassigned before the assignment, or a compile-time error occurs.

The remainder of this chapter is devoted to a precise explanation of the words "definitely assigned before" and "definitely unassigned before".

The idea behind definite assignment is that an assignment to the local variable or blankfinal field must occur on every possible execution path to the access. Similarly, the idea behind definite unassignment is that no other assignment to the blankfinal variable is permitted to occur on any possible execution path to an assignment.

The analysis takes into account the structure of statements and expressions; it also provides a special treatment of the expression operators!,&&,||, and? :, and of boolean-valued constant expressions.

Except for the special treatment of the conditional boolean operators&&,||, and? : and of boolean-valued constant expressions, the values of expressions are not taken into account in the flow analysis.

Example 16-1. Definite Assignment Considers Structure of Statements and Expressions

A Java compiler recognizes thatk 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

istrue, and the value can betrue only if the assignment tok 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 variablek is definitely assigned by thewhile statement because the condition expressiontrue never has the valuefalse, so only thebreak statement can cause thewhile statement to complete normally, andk is definitely assigned before thebreak statement.

On the other hand, the code:

{    int k;    while (n < 4) {        k = n;        if (k >= 5) break;        n = 6;    }    System.out.println(k);  /* k is not "definitely assigned"                               before this statement */}

must be rejected by a Java compiler, because in this case thewhile statement is not guaranteed to execute its body as far as the rules of definite assignment are concerned.


Example 16-2. Definite Assignment Does Not Consider Values of Expressions

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 statement */}

even though the value ofn is known at compile time, and in principle it can be known at compile time that the assignment tok 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 expressionn > 2 is not a constant expression as defined in§15.28.

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 ofk is concerned, because the rules outlined in this section allow it to tell thatk is assigned no matter whether theflag istrue orfalse. 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 this statement */}

and so compiling this program must cause a compile-time error to occur.


Example 16-3. Definite Unassignment

A Java compiler will accept the code:

void unflow(boolean flag) {    final int k;    if (flag) {        k = 3;        System.out.println(k);    }    else {        k = 4;        System.out.println(k);    }}

as far as definite unassignment ofk is concerned, because the rules outlined in this section allow it to tell thatk is assigned at most once (indeed, exactly once) no matter whether theflag istrue orfalse. But the rules do not accept the variation:

void unflow(boolean flag) {    final int k;    if (flag) {        k = 3;        System.out.println(k);    }    if (!flag) {        k = 4;        System.out.println(k);  /* k is not "definitely unassigned"                                   before this statement */    }}

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 several technical terms:

For boolean-valued expressions, the last two are refined into four cases:

Here,when true andwhen false refer to the value of the expression.

For example, the local variablek is definitely assigned a value after evaluation of the expression:

a && ((k=m) > 5)

when the expression istrue but not when the expression isfalse (because ifa is false, then the assignment tok is not necessarily executed (more properly, evaluated)).

The phrase "V is definitely assigned afterX" (whereV is a local variable andX is a statement or expression) means "V is definitely assigned afterX ifX completes normally". IfX completes abruptly, the assignment need not have occurred, and the rules stated here take this into account.

A peculiar consequence of this definition is that "V is definitely assigned afterbreak;" is always true! Because abreak statement never completes normally, it is vacuously true thatV has been assigned a value if thebreak statement completes normally.

The statement "V is definitely unassigned afterX" (whereV is a variable andX is a statement or expression) means "V is definitely unassigned afterX ifX completes normally".

An even more peculiar consequence of this definition is that "V is definitely unassigned afterbreak;" is always true! Because abreak statement never completes normally, it is vacuously true thatV has not been assigned a value if thebreak statement completes normally. (For that matter, it is also vacuously true that the moon is made of green cheese if thebreak statement completes normally.)

In all, there are four possibilities for a variableV after a statement or expression has been executed:

To shorten the rules, the customary abbreviation "iff" is used to mean "if and only if". We also use an abbreviation convention: if a rule contains one or more occurrences of "[un]assigned" then it stands for two rules, one with every occurrence of "[un]assigned" replaced by "definitely assigned" and one with every occurrence of "[un]assigned" replaced by "definitely unassigned".

For example:

  • V is [un]assigned after an empty statement iff it is [un]assigned before the empty statement.

should be understood to stand for two rules:

  • V is definitely assigned after an empty statement iff it is definitely assigned before the empty statement.

  • V is definitely unassigned after an empty statement iff it is definitely unassigned before the empty statement.

Throughout the rest of this chapter, we will, unless explicitly stated otherwise, writeV to represent a local variable or blankfinal field which is in scope (§6.3). Likewise, we will usea,b,c, ande to represent expressions, andS andT to represent statements. We will use the phrase "a isV" to mean thata is either the simple name of the variableV, orV's simple name qualified bythis (ignoring parentheses). We will use the phrase "a is notV" to mean the negation of "a isV".

The definite unassignment analysis of loop statements raises a special problem. Consider the statementwhile (e)S. In order to determine whetherV is definitely unassigned within some subexpression ofe, we need to determine whetherV is definitely unassigned beforee. One might argue, by analogy with the rule for definite assignment (§16.2.10), thatV is definitely unassigned beforee iff it is definitely unassigned before thewhile statement. However, such a rule is inadequate for our purposes. Ife evaluates totrue, the statementS will be executed. Later, ifV is assigned byS, then in the following iteration(s)V will have already been assigned whene is evaluated. Under the rule suggested above, it would be possible to assignV multiple times, which is exactly what we have sought to avoid by introducing these rules.

A revised rule would be: "V is definitely unassigned beforee iff it is definitely unassigned before thewhile statement and definitely unassigned afterS". However, when we formulate the rule forS, we find: "V is definitely unassigned beforeS iff it is definitely unassigned aftere when true". This leads to a circularity. In effect,V is definitely unassignedbefore the loop conditione only if it is unassignedafter the loop as a whole!

We break this vicious circle using a hypothetical analysis of the loop condition and body. For example, if we assume thatV is definitely unassigned beforee (regardless of whetherV really is definitely unassigned beforee), and can then prove thatV was definitely unassigned aftere then we know thate does not assignV. This is stated more formally as:

AssumingV is definitely unassigned beforee,V is definitely unassigned aftere.

Variations on the above analysis are used to define well founded definite unassignment rules for all loop statements in the Java programming language.

16.1. Definite Assignment and Expressions

16.1.1. Boolean Constant Expressions

  • V is [un]assigned after any constant expression (§15.28) whose value istrue when false.

  • V is [un]assigned after any constant expression whose value isfalse when true.

  • V is [un]assigned after any constant expression whose value istrue when true iffV is [un]assigned before the constant expression.

  • V is [un]assigned after any constant expression whose value isfalse when false iffV is [un]assigned before the constant expression.

  • V is [un]assigned after a boolean-valued constant expressione iffV is [un]assigned aftere when true andV is [un]assigned aftere when false.

    This is equivalent to saying thatV is [un]assigned aftere iffV is [un]assigned beforee.

Because a constant expression whose value istrue never has the valuefalse, and a constant expression whose value isfalse never has the valuetrue, the first two rules are vacuously satisfied. They are helpful in analyzing expressions involving the operators&& (§16.1.2),|| (§16.1.3),! (§16.1.4), and? : (§16.1.5).

16.1.2. Conditional-And Operator&&

  • V is [un]assigned aftera&&b (§15.23) when true iffV is [un]assigned afterb when true.

  • V is [un]assigned aftera&&b when false iffV is [un]assigned aftera when false andV is [un]assigned afterb when false.

  • V is [un]assigned beforea iffV is [un]assigned beforea&&b.

  • V is [un]assigned beforeb iffV is [un]assigned aftera when true.

  • V is [un]assigned aftera&&b iffV is [un]assigned aftera&&b when true andV is [un]assigned aftera&&b when false.

16.1.3. Conditional-Or Operator||

  • V is [un]assigned aftera||b (§15.24) when true iffV is [un]assigned aftera when true andV is [un]assigned afterb when true.

  • V is [un]assigned aftera||b when false iffV is [un]assigned afterb when false.

  • V is [un]assigned beforea iffV is [un]assigned beforea||b.

  • V is [un]assigned beforeb iffV is [un]assigned aftera when false.

  • V is [un]assigned aftera||b iffV is [un]assigned aftera||b when true andV is [un]assigned aftera||b when false.

16.1.4. Logical Complement Operator!

  • V is [un]assigned after!a (§15.15.6) when true iffV is [un]assigned aftera when false.

  • V is [un]assigned after!a when false iffV is [un]assigned aftera when true.

  • V is [un]assigned beforea iffV is [un]assigned before!a.

  • V is [un]assigned after!a iffV is [un]assigned after!a when true andV is [un]assigned after!a when false.

    This is equivalent to saying thatV is [un]assigned after!a iffV is [un]assigned aftera.

16.1.5. Conditional Operator? :

Suppose thatb andc are boolean-valued expressions.

  • V is [un]assigned aftera?b:c (§15.25) when true iffV is [un]assigned afterb when true andV is [un]assigned afterc when true.

  • V is [un]assigned aftera?b:c when false iffV is [un]assigned afterb when false andV is [un]assigned afterc when false.

  • V is [un]assigned beforea iffV is [un]assigned beforea?b:c.

  • V is [un]assigned beforeb iffV is [un]assigned aftera when true.

  • V is [un]assigned beforec iffV is [un]assigned aftera when false.

  • V is [un]assigned aftera?b:c iffV is [un]assigned aftera?b:c when true andV is [un]assigned aftera?b:c when false.

16.1.6. Conditional Operator? :

Suppose thatb andc are expressions that are not boolean-valued.

  • V is [un]assigned aftera?b:c (§15.25) iffV is [un]assigned afterb andV is [un]assigned afterc.

  • V is [un]assigned beforea iffV is [un]assigned beforea?b:c.

  • V is [un]assigned beforeb iffV is [un]assigned aftera when true.

  • V is [un]assigned beforec iffV is [un]assigned aftera when false.

16.1.7. Other Expressions of Typeboolean

Suppose thate is an expression of typeboolean and is not a boolean constant expression, logical complement expression!a, conditional-and expressiona&&b, conditional-or expressiona||b, or conditional expressiona?b:c.

  • V is [un]assigned aftere when true iffV is [un]assigned aftere.

  • V is [un]assigned aftere when false iffV is [un]assigned aftere.

16.1.8. Assignment Expressions

Consider an assignment expressiona=b,a+=b,a-=b,a*=b,a/=b,a%=b,a<<=b,a>>=b,a>>>=b,a&=b,a|=b, ora^=b (§15.26).

  • V is definitely assigned after the assignment expression iff either:

    • a isV, or

    • V is definitely assigned afterb.

  • V is definitely unassigned after the assignment expression iffa is notV andV is definitely unassigned afterb.

  • V is [un]assigned beforea iffV is [un]assigned before the assignment expression.

  • V is [un]assigned beforeb iffV is [un]assigned aftera.

Note that ifa isV andV is not definitely assigned before a compound assignment such asa&=b, then a compile-time error will necessarily occur. The first rule for definite assignment stated above includes the disjunct "a isV" even for compound assignment expressions, not just simple assignments, so thatV will be considered to have been definitely assigned at later points in the code. Including the disjunct "a isV" 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. A similar remark applies to the inclusion of the conjunct "a is notV" in the first rule for definite unassignment stated above.

16.1.9. Operators++ and--

  • V is definitely assigned after++a (§15.15.1),--a (§15.15.2),a++ (§15.14.2), ora-- (§15.14.3) iff eithera isV orV is definitely assigned after the operand expression.

  • V is definitely unassigned after++a,--a,a++, ora-- iffa is notV andV is definitely unassigned after the operand expression.

  • V is [un]assigned beforea iffV is [un]assigned before++a,--a,a++, ora--.

16.1.10. Other Expressions

If an expression is not a boolean constant expression, and is not a preincrement expression++a, predecrement expression--a, postincrement expressiona++, postdecrement expressiona--, logical complement expression!a, conditional-and expressiona&&b, conditional-or expressiona||b, conditional expressiona?b:c, or assignment expression, then the following rules apply:

  • If the expression has no subexpressions,V is [un]assigned after the expression iffV is [un]assigned before the expression.

    This case applies to literals, names,this (both qualified and unqualified), unqualified class instance creation expressions with no arguments, initialized array creation expressions whose initializers contain no expressions, unqualified superclass field access expressions, named method invocations with no arguments, and unqualified superclass method invocations with no arguments.

  • If the expression has subexpressions,V is [un]assigned after the expression iffV is [un]assigned after its rightmost immediate subexpression.

There is a piece of subtle reasoning behind the assertion that a variableV can be known to be definitely unassigned after a method invocation. Taken by itself, at face value and without qualification, such an assertion is not always true, because an invoked method can perform assignments. But it must be remembered that, for the purposes of the Java programming language, the concept of definite unassignment is applied only to blankfinal variables. IfV is a blankfinal local variable, then only the method to which its declaration belongs can perform assignments toV. IfV is a blankfinal field, then only a constructor or an initializer for the class containing the declaration forV can perform assignments toV; no method can perform assignments toV. Finally, explicit constructor invocations (§8.8.7.1) are handled specially (§16.9); although they are syntactically similar to expression statements containing method invocations, they are not expression statements and therefore the rules of this section do not apply to explicit constructor invocations.

For any immediate subexpressiony of an expressionx,V is [un]assigned beforey iff one of the following is true:

  • y is the leftmost immediate subexpression ofx andV is [un]assigned beforex.

  • y is the right-hand operand of a binary operator andV is [un]assigned after the left-hand operand.

  • x is an array access,y is the subexpression within the brackets, andV is [un]assigned after the subexpression before the brackets.

  • x is a primary method invocation expression,y is the first argument expression in the method invocation expression, andV is [un]assigned after the primary expression that computes the target object.

  • x is a method invocation expression or a class instance creation expression;y is an argument expression, but not the first; andV is [un]assigned after the argument expression to the left ofy.

  • x is a qualified class instance creation expression,y is the first argument expression in the class instance creation expression, andV is [un]assigned after the primary expression that computes the qualifying object.

  • x is an array instance creation expression;y is a dimension expression, but not the first; andV is [un]assigned after the dimension expression to the left ofy.

  • x is an array instance creation expression initialized via an array initializer;y is the array initializer inx; andV is [un]assigned after the dimension expression to the left ofy.

16.2. Definite Assignment and Statements

16.2.1. Empty Statements

  • V is [un]assigned after an empty statement (§14.6) iff it is [un]assigned before the empty statement.

16.2.2. Blocks

  • A blankfinal member fieldV is definitely assigned (and moreover is not definitely unassigned) before the block (§14.2) that is the body of any method in the scope ofV and before the declaration of any class declared within the scope ofV.

  • A local variableV is definitely unassigned (and moreover is not definitely assigned) before the block that is the body of the constructor, method, instance initializer or static initializer that declaresV.

  • LetC be a class declared within the scope ofV. ThenV is definitely assigned before the block that is the body of any constructor, method, instance initializer, or static initializer declared inC iffV is definitely assigned before the declaration ofC.

    Note that there are no rules that would allow us to conclude thatV is definitely unassigned before the block that is the body of any constructor, method, instance initializer, or static initializer declared inC. We can informally conclude thatV is not definitely unassigned before the block that is the body of any constructor, method, instance initializer, or static initializer declared inC, but there is no need for such a rule to be stated explicitly.

  • V is [un]assigned after an empty block iffV is [un]assigned before the empty block.

  • V is [un]assigned after a non-empty block iffV is [un]assigned after the last statement in the block.

  • V is [un]assigned before the first statement of the block iffV is [un]assigned before the block.

  • V is [un]assigned before any other statementS of the block iffV is [un]assigned after the statement immediately precedingS in the block.

We say thatV is definitely unassigned everywhere in a blockB iff:

  • V is definitely unassigned beforeB.

  • V is definitely assigned aftere in every assignment expressionV=e,V+=e,V-=e,V*=e,V/=e,V%=e,V<<=e,V>>=e,V>>>=e,V&=e,V|=e, orV^=e that occurs inB.

  • V is definitely assigned before every expression++V,--V,V++, orV-- that occurs inB.

These conditions are counterintuitive and require some explanation. Consider a simple assignmentV=e. IfV is definitely assigned aftere, then either:

  • The assignment occurs in dead code, andV is vacuously definitely assigned. In this case, the assignment will not actually take place, and we can assume thatV is not being assigned by the assignment expression. Or:

  • V was already assigned by an earlier expression prior toe. In this case the current assignment will cause a compile-time error.

So, we can conclude that if the conditions are met by a program that causes no compile time error, then any assignments toV inB will not actually take place at run time.

16.2.3. Local Class Declaration Statements

  • V is [un]assigned after a local class declaration statement (§14.3) iffV is [un]assigned before the local class declaration statement.

16.2.4. Local Variable Declaration Statements

  • V is [un]assigned after a local variable declaration statement (§14.4) that contains no variable initializers iffV is [un]assigned before the local variable declaration statement.

  • V is definitely assigned after a local variable declaration statement that contains at least one variable initializer iff eitherV is definitely assigned after the last variable initializer in the local variable declaration statement or the last variable initializer in the declaration is in the declarator that declaresV.

  • V is definitely unassigned after a local variable declaration statement that contains at least one variable initializer iffV is definitely unassigned after the last variable initializer in the local variable declaration statement and the last variable initializer in the declaration is not in the declarator that declaresV.

  • V is [un]assigned before the first variable initializer in a local variable declaration statement iffV is [un]assigned before the local variable declaration statement.

  • V is definitely assigned before any variable initializere other than the first one in the local variable declaration statement iff eitherV is definitely assigned after the variable initializer to the left ofe or the initializer expression to the left ofe is in the declarator that declaresV.

  • V is definitely unassigned before any variable initializere other than the first one in the local variable declaration statement iffV is definitely unassigned after the variable initializer to the left ofe and the initializer expression to the left ofe is not in the declarator that declaresV.

16.2.5. Labeled Statements

  • V is [un]assigned after a labeled statementL:S (whereL is a label) (§14.7) iffV is [un]assigned afterS andV is [un]assigned before everybreak statement that may exit the labeled statementL:S.

  • V is [un]assigned beforeS iffV is [un]assigned beforeL:S.

16.2.6. Expression Statements

  • V is [un]assigned after an expression statemente; (§14.8) iff it is [un]assigned aftere.

  • V is [un]assigned beforee iff it is [un]assigned beforee;.

16.2.7. if Statements

The following rules apply to a statementif (e)S (§14.9.1):

  • V is [un]assigned afterif (e)S iffV is [un]assigned afterS andV is [un]assigned aftere when false.

  • V is [un]assigned beforee iffV is [un]assigned beforeif (e)S.

  • V is [un]assigned beforeS iffV is [un]assigned aftere when true.

The following rules apply to a statementif (e)S elseT (§14.9.2):

  • V is [un]assigned afterif (e)S elseT iffV is [un]assigned afterS andV is [un]assigned afterT.

  • V is [un]assigned beforee iffV is [un]assigned beforeif (e)S elseT.

  • V is [un]assigned beforeS iffV is [un]assigned aftere when true.

  • V is [un]assigned beforeT iffV is [un]assigned aftere when false.

16.2.8. assert Statements

The following rules apply both to a statementasserte1 and to a statementasserte1 :e2 (§14.10):

  • V is [un]assigned beforee1 iffV is [un]assigned before theassert statement.

  • V is definitely assigned after theassert statement iffV is definitely assigned before theassert statement.

  • V is definitely unassigned after theassert statement iffV is definitely unassigned before theassert statement andV is definitely unassigned aftere1 when true.

The following rule applies to a statementasserte1 :e2 :

  • V is [un]assigned beforee2 iffV is [un]assigned aftere1 when false.

16.2.9. switch Statements

  • V is [un]assigned after aswitch statement (§14.11) iff all of the following are true:

    • Either there is adefault label in the switch block orV is [un]assigned after the switch expression.

    • Either there are no switch labels in the switch block that do not begin a block-statement-group (that is, there are no switch labels immediately before the "}" that ends the switch block) orV is [un]assigned after the switch expression.

    • Either the switch block contains no block-statement-groups orV is [un]assigned after the last block-statement of the last block-statement-group.

    • V is [un]assigned before everybreak statement that may exit theswitch statement.

  • V is [un]assigned before the switch expression iffV is [un]assigned before theswitch statement.

If a switch block contains at least one block-statement-group, then the following rules also apply:

  • V is [un]assigned before the first block-statement of the first block-statement-group in the switch block iffV is [un]assigned after the switch expression.

  • V is [un]assigned before the first block-statement of any block-statement-group other than the first iffV is [un]assigned after the switch expression andV is [un]assigned after the preceding block-statement.

16.2.10. while Statements

  • V is [un]assigned afterwhile (e)S (§14.12) iffV is [un]assigned aftere when false andV is [un]assigned before everybreak statement for which thewhile statement is the break target.

  • V is definitely assigned beforee iffV is definitely assigned before thewhile statement.

  • V is definitely unassigned beforee iff all of the following are true:

    • V is definitely unassigned before thewhile statement.

    • AssumingV is definitely unassigned beforee,V is definitely unassigned afterS.

    • AssumingV is definitely unassigned beforee,V is definitely unassigned before everycontinue statement for which thewhile statement is the continue target.

  • V is [un]assigned beforeS iffV is [un]assigned aftere when true.

16.2.11. do Statements

  • V is [un]assigned afterdoS while (e); (§14.13) iffV is [un]assigned aftere when false andV is [un]assigned before everybreak statement for which thedo statement is the break target.

  • V is definitely assigned beforeS iffV is definitely assigned before thedo statement.

  • V is definitely unassigned beforeS iff all of the following are true:

    • V is definitely unassigned before thedo statement.

    • AssumingV is definitely unassigned beforeS,V is definitely unassigned aftere when true.

  • V is [un]assigned beforee iffV is [un]assigned afterS andV is [un]assigned before everycontinue statement for which thedo statement is the continue target.

16.2.12. for Statements

The rules herein cover the basicfor statement (§14.14.1). Since the enhancedfor statement (§14.14.2) is defined by translation to a basicfor statement, no special rules need to be provided for it.

  • V is [un]assigned after afor statement iff both of the following are true:

    • Either a condition expression is not present orV is [un]assigned after the condition expression when false.

    • V is [un]assigned before everybreak statement for which thefor statement is the break target.

  • V is [un]assigned before the initialization part of thefor statement iffV is [un]assigned before thefor statement.

  • V is definitely assigned before the condition part of thefor statement iffV is definitely assigned after the initialization part of thefor statement.

  • V is definitely unassigned before the condition part of thefor statement iff all of the following are true:

    • V is definitely unassigned after the initialization part of thefor statement.

    • AssumingV is definitely unassigned before the condition part of thefor statement,V is definitely unassigned after the contained statement.

    • AssumingV is definitely unassigned before the contained statement,V is definitely unassigned before everycontinue statement for which thefor statement is the continue target.

  • V is [un]assigned before the contained statement iff either of the following is true:

    • A condition expression is present andV is [un]assigned after the condition expression when true.

    • No condition expression is present andV is [un]assigned after the initialization part of thefor statement.

  • V is [un]assigned before the incrementation part of thefor statement iffV is [un]assigned after the contained statement andV is [un]assigned before everycontinue statement for which thefor statement is the continue target.

16.2.12.1. Initialization Part offor Statement

  • If the initialization part of thefor statement is a local variable declaration statement, the rules of§16.2.4 apply.

  • Otherwise, if the initialization part is empty, thenV is [un]assigned after the initialization part iffV is [un]assigned before the initialization part.

  • Otherwise, three rules apply:

    • V is [un]assigned after the initialization part iffV is [un]assigned after the last expression statement in the initialization part.

    • V is [un]assigned before the first expression statement in the initialization part iffV is [un]assigned before the initialization part.

    • V is [un]assigned before an expression statementS other than the first in the initialization part iffV is [un]assigned after the expression statement immediately precedingS.

16.2.12.2. Incrementation Part offor Statement

  • If the incrementation part of thefor statement is empty, thenV is [un]assigned after the incrementation part iffV is [un]assigned before the incrementation part.

  • Otherwise, three rules apply:

    • V is [un]assigned after the incrementation part iffV is [un]assigned after the last expression statement in the incrementation part.

    • V is [un]assigned before the first expression statement in the incrementation part iffV is [un]assigned before the incrementation part.

    • V is [un]assigned before an expression statementS other than the first in the incrementation part iffV is [un]assigned after the expression statement immediately precedingS.

16.2.13. break,continue,return, andthrow Statements

  • By convention, we say thatV is [un]assigned after anybreak,continue,return, orthrow statement (§14.15,§14.16,§14.17,§14.18).

    The notion that a variable is "[un]assigned after" a statement or expression really means "is [un]assigned after the statement or expression completes normally". Because abreak,continue,return, orthrow statement never completes normally, it vacuously satisfies this notion.

  • In areturn statement with an expressione or athrow statement with an expressione,V is [un]assigned beforee iffV is [un]assigned before thereturn orthrow statement.

16.2.14. synchronized Statements

  • V is [un]assigned aftersynchronized (e)S (§14.19) iffV is [un]assigned afterS.

  • V is [un]assigned beforee iffV is [un]assigned before the statementsynchronized (e)S.

  • V is [un]assigned beforeS iffV is [un]assigned aftere.

16.2.15. try Statements

These rules apply to everytry statement (§14.20), whether or not it has afinally block:

  • V is [un]assigned before thetry block iffV is [un]assigned before thetry statement.

  • V is definitely assigned before acatch block iffV is definitely assigned before thetry block.

  • V is definitely unassigned before acatch block iff all of the following are true:

    • V is definitely unassigned after thetry block.

    • V is definitely unassigned before everyreturn statement that belongs to thetry block.

    • V is definitely unassigned aftere in every statement of the formthrowe that belongs to thetry block.

    • V is definitely unassigned after everyassert statement that occurs in thetry block.

    • V is definitely unassigned before everybreak statement that belongs to thetry block and whose break target contains (or is) thetry statement.

    • V is definitely unassigned before everycontinue statement that belongs to thetry block and whose continue target contains thetry statement.

If atry statement does not have afinally block, then this rule also applies:

  • V is [un]assigned after thetry statement iffV is [un]assigned after thetry block andV is [un]assigned after everycatch block in thetry statement.

If atry statement does have afinally block, then these rules also apply:

  • V is definitely assigned after thetry statement iff at least one of the following is true:

    • V is definitely assigned after thetry block andV is definitely assigned after everycatch block in thetry statement.

    • V is definitely assigned after thefinally block.

    • V is definitely unassigned after atry statement iffV is definitely unassigned after thefinally block.

  • V is definitely assigned before thefinally block iffV is definitely assigned before thetry statement.

  • V is definitely unassigned before thefinally block iff all of the following are true:

    • V is definitely unassigned after thetry block.

    • V is definitely unassigned before everyreturn statement that belongs to thetry block.

    • V is definitely unassigned aftere in every statement of the formthrowe that belongs to thetry block.

    • V is definitely unassigned after everyassert statement that occurs in thetry block.

    • V is definitely unassigned before everybreak statement that belongs to thetry block and whose break target contains (or is) thetry statement.

    • V is definitely unassigned before everycontinue statement that belongs to thetry block and whose continue target contains thetry statement.

    • V is definitely unassigned after everycatch block of thetry statement.

16.3. Definite Assignment and Parameters

  • A formal parameterV of a method or constructor (§8.4.1,§8.8.1) is definitely assigned (and moreover is not definitely unassigned) before the body of the method or constructor.

  • An exception parameterV of acatch clause (§14.20) is definitely assigned (and moreover is not definitely unassigned) before the body of thecatch clause.

16.4. Definite Assignment and Array Initializers

  • V is [un]assigned after an empty array initializer (§10.6) iffV is [un]assigned before the empty array initializer.

  • V is [un]assigned after a non-empty array initializer iffV is [un]assigned after the last variable initializer in the array initializer.

  • V is [un]assigned before the first variable initializer of the array initializer iffV is [un]assigned before the array initializer.

  • V is [un]assigned before any other variable initializere of the array initializer iffV is [un]assigned after the variable initializer to the left ofe in the array initializer.

16.5. Definite Assignment and Enum Constants

The rules determining when a variable is definitely assigned or definitely unassigned before an enum constant (§8.9.1) are given in§16.8.

This is because an enum constant is essentially astaticfinal field (§8.3.1.1,§8.3.1.2) that is initialized with a class instance creation expression (§15.9).

  • V is definitely assigned before the declaration of a class body of an enum constant with no arguments that is declared within the scope ofV iffV is definitely assigned before the enum constant.

  • V is definitely assigned before the declaration of a class body of an enum constant with arguments that is declared within the scope ofV iffV is definitely assigned after the last argument expression of the enum constant

The definite assignment/unassignment status of any construct within the class body of an enum constant is governed by the usual rules for classes.

  • V is [un]assigned before the first argument to an enum constant iff it is [un]assigned before the enum constant.

  • V is [un]assigned beforey (an argument of an enum constant, but not the first) iffV is [un]assigned after the argument to the left ofy.

16.6. Definite Assignment and Anonymous Classes

  • V is definitely assigned before an anonymous class declaration (§15.9.5) that is declared within the scope ofV iffV is definitely assigned after the class instance creation expression that declares the anonymous class.

It should be clear that if an anonymous class is implicitly defined by an enum constant, the rules of§16.5 apply.

16.7. Definite Assignment and Member Types

LetC be a class, and letV be a blankfinal member field ofC. Then:

  • V is definitely assigned (and moreover, not definitely unassigned) before the declaration of any member type (§8.5,§9.5) ofC.

LetC be a class declared within the scope ofV. Then:

  • V is definitely assigned before a member type declaration ofC iffV is definitely assigned before the declaration ofC.

16.8. Definite Assignment and Static Initializers

LetC be a class declared within the scope ofV. Then:

  • V is definitely assigned before an enum constant (§8.9.1) or static variable initializer (§8.3.2) ofC iffV is definitely assigned before the declaration ofC.

    Note that there are no rules that would allow us to conclude thatV is definitely unassigned before a static variable initializer or enum constant. We can informally conclude thatV is not definitely unassigned before any static variable initializer ofC, but there is no need for such a rule to be stated explicitly.

LetC be a class, and letV be a blankstaticfinal member field ofC, declared inC. Then:

  • V is definitely unassigned (and moreover is not definitely assigned) before the leftmost enum constant, static initializer (§8.7), or static variable initializer ofC.

  • V is [un]assigned before an enum constant, static initializer, or static variable initializer ofC other than the leftmost iffV is [un]assigned after the preceding enum constant, static initializer, or static variable initializer ofC.

LetC be a class, and letV be a blankstaticfinal member field ofC, declared in a superclass ofC. Then:

  • V is definitely assigned (and moreover is not definitely unassigned) before every enum constant ofC.

  • V is definitely assigned (and moreover is not definitely unassigned) before the block that is the body of a static initializer ofC.

  • V is definitely assigned (and moreover is not definitely unassigned) before every static variable initializer ofC.

16.9. Definite Assignment, Constructors, and Instance Initializers

LetC be a class declared within the scope ofV. Then:

  • V is definitely assigned before an instance variable initializer (§8.3.2) ofC iffV is definitely assigned before the declaration ofC.

    Note that there are no rules that would allow us to conclude thatV is definitely unassigned before an instance variable initializer. We can informally conclude thatV is not definitely unassigned before any instance variable initializer ofC, but there is no need for such a rule to be stated explicitly.

LetC be a class, and letV be a blankfinal non-static member field ofC, declared inC. Then:

  • V is definitely unassigned (and moreover is not definitely assigned) before the leftmost instance initializer (§8.6) or instance variable initializer ofC.

  • V is [un]assigned before an instance initializer or instance variable initializer ofC other than the leftmost iffV is [un]assigned after the preceding instance initializer or instance variable initializer ofC.

The following rules hold within the constructors (§8.8.7) of classC:

  • V is definitely assigned (and moreover is not definitely unassigned) after an alternate constructor invocation (§8.8.7.1).

  • V is definitely unassigned (and moreover is not definitely assigned) before an explicit or implicit superclass constructor invocation (§8.8.7.1).

  • IfC has no instance initializers or instance variable initializers, thenV is not definitely assigned (and moreover is definitely unassigned) after an explicit or implicit superclass constructor invocation.

  • IfC has at least one instance initializer or instance variable initializer thenV is [un]assigned after an explicit or implicit superclass constructor invocation iffV is [un]assigned after the rightmost instance initializer or instance variable initializer ofC.

LetC be a class, and letV be a blankfinal member field ofC, declared in a superclass ofC. Then:

  • V is definitely assigned (and moreover is not definitely unassigned) before the block that is the body of a constructor or instance initializer ofC.

  • V is definitely assigned (and moreover is not definitely unassigned) before every instance variable initializer ofC.


Prev   Next
Chapter 15. Expressions Home Chapter 17. Threads and Locks

Legal Notice

[8]ページ先頭

©2009-2025 Movatter.jp