Javatpoint Logo
Javatpoint Logo

Definite Assignment in Java

Every local variable and the final blank field will have an assigned value when any value is accessed. Access to the value will consist of the variable's name or an area that occurs in an expression, except in the left-hand operand of the assignment operator, "=".

To access a local variable or final blank field x, this "x" must be assigned definitely before accessing it or else a compile-time error will occur.

In the same way, every final blank variable will be assigned once and unassigned if an assignment to it occurs.

So, that kind of assignment is defined to occur only if the variable's name had happened on the left-hand side of an assignment operator.

When the assignment is done to a final blank variable, that variable should not get assigned previously before this assignment or else a compile-time error will arise.

The main idea behind this definite assignment is that the local variable assignment or final blank field will occur on each possible execution path for the access.

So that the analysis will take into account the structure of expressions and statements, and it will provide immediate treatment of the operators in an expression like &&, !, ||,? : and also boolean-valued constant expressions.

There is an exception for the treatment with conditional boolean operators like &&, ||, and ?: and also with boolean-valued constant expressions, and the values of the expressions are not considered in the flow analysis.

Let us discuss this with an example.

The definite assignment will consider the structure of expressions and statements.

The Java compiler will decide that "k" is assigned before its access, like an argument with the method invocation in the code.

It is because the access will occur if the value of the expression is accurate. That value is valid only if the assignment to the "k" is executed and more adequately evaluated. The expression is given below:

And similarly, a Java compiler will recognize that in the above code, the variable "k" is definitely assigned to the while statement because the conditional expression "TRUE" will never have the value "FALSE". The break statement only will cause the while statement to compile as usual, and variable "k" is definitely assigned before the break statement.

And also, on the other hand,

The Java compiler will reject the above code because, in the above case, the while statement is not correct to execute its body only if we consider the rules of definite assignment.

Another example

The Java compiler will produce a compile-time error for the above code even though the "n" value is known at the compilation time. In the rule, it can be known at the time of compilation that the assignment to the value "k" always be executed and, more appropriately, it will execute.

The Java compiler must follow the rules we discussed above. The constant expressions only follow the rules, and in the above example, the constant expression, n > 2, is not a constant expression.

We will discuss another example of the Java compiler will accept the code:

As far as we consider the definite assignment of "k" because the rules are broken in the above, and we are allowed to say that "k" is assigned whether th value of the flag is true or false.

The rules will not accept the above variation, and the program will get the compile time error.

Example of Definite Unassignment

The Java compiler will accept the code until a definite unassignment of "k" is concerned, and the rules crossed in this will allow it to tell that "k" is assigned only once, like nothing matters if it is true or false.

The rules will not accept the variation, but when we compile the above program, it gets the compile-time error.

For specifying the steps of definite assignment, these rules will define many technical terms:

  1. It has to check the variable is definitely assigned before any expression or statement.
  2. It has to check the variable is definitely unassigned before any expression or statement.
  3. It has to check the variable is definitely assigned after any expression or statement.
  4. It has to check the variable is definitely unassigned after any expression or statement.

In the case of Boolean-valued expressions, the last two steps in the above are redirected into four points:

  1. If it is true, the variable is definitely assigned after the expression.
  2. If it is true, the variable is definitely unassigned after the expression.
  3. If it is false, the variable is definitely assigned after the expression.
  4. If it is false, the variable is definitely unassigned after the expression.

From the above, the true and false will refer to the value of the expression.

Let us take an example.

The local variable "k" is definitely assigned to a value after evaluating the expression above only if the above expression is true and not when the expression is false. If "a" is false, then the assignment for the "K" is not executed correctly or evaluated.

Let us consider the statement "V is definitely assigned after X", "V" is the local variable and "X" is the expression or statement. The statement says that "V" is definitely assigned after "X" if "X" completes its functioning usually. Suppose "X" has been completed in the wrong way, and the rules are defined for taking into consideration.

The different situation of the above expression is that "V is definitely assigned after the break," and it is always true because we know that the break statement will not usually be complete. It is true that "V" had not assigned the value of the break statement that usually completes them.

  1. "V" is definitely assigned but not definitely unassigned. The analysis of flow rules will prove that an assignment to "V" has occurred.
  2. "V" is definitely unassigned but not definitely assigned, and the analysis flow rules will prove that an assignment to "V" has not occurred.
  3. "V" is not definitely assigned; it is not definitely unassigned, and the rule will not prove that an assignment to V has occurred.
  4. "V" is definitely assigned and also definitely unassigned, and it is not possible to the statement for completing usually.

The abbreviation "iff" is used as "if and only if" to shorten the rules. We can also use another acronym, like if a rule may contain one or more occurrences of "unassigned", then it performs two rules:

  1. The one with each occurrence of "unassigned" is replaced by "definitely assigned".
  2. The other, with each occurrence of "unassigned", is replaced with "definitely unassigned'.

Let us take an example.

  1. "V" is unassigned only after an empty statement iff it is unassigned before the empty statement.

The above statement is understood by two rules given below:

  1. "V" is assigned after an empty statement iff it is assigned before the empty statement.
  2. "V" is definitely unassigned after an empty statement iff it is definitely unassigned before th empty statement.

Definite assignment and expressions

Boolean constant expressions

  1. "V" is unassigned after some constant expression where the value is true when false.
  2. "V" is unassigned after some constant expression where the value is false when true.
  3. "V" is unassigned after some constant expression where the value is true when true iff "V" is unassigned before the constant expression.
  4. "V" is unassigned after any constant expression where the value is false when false iff "V" is unassigned before the constant expression.
  5. "V" is unassigned after a boolean-valued constant expression "e" iff "V" is unassigned after "e" and it is true, and "V" is unassigned after "e" when it is false.

Above all are equivalent to saying that "V" is unassigned or assigned after "e" iff "V" is unassigned or assigned before "e".

It is because of the constant expression where the value is true and never had the value as false and the constant expression where the value is false and never had the value true, and the above two rules are satisfied.

Conditional-And operator (&&)

  1. If a&&b is true, then "V" is unassigned or assigned, iff "V" is unassigned after b, when true.
  2. "V" is unassigned or assigned after a&&b when false if and only if "V" is assigned or unassigned after "a" when it is false and also "V" is unassigned or assigned after "b" when false.
  3. "V" is unassigned or assigned before "a" if and only if "V" is unassigned or assigned before a&&b.
  4. "V" is unassigned or assigned before "b" if and only if "V" is unassigned or assigned after "a" when it is true.
  5. "V" is [un]assigned after a&&b if and only if "V" is [un]assigned after a&&b when true and "V" is [un]assigned after a&&b when false.

Conditional-Or operator (||)

  1. a||b is true only when "V" is assigned after a and "V" is assigned after b, and when both are true, a||b becomes true.
  2. "V" is unassigned or assigned after a||b when false if and only if "V" is unassigned or assigned after b when it is false.
  3. "V" is unassigned or assigned before a if and only if "V" is unassigned or assigned before a||b.
  4. "V" is assigned or unassigned before b if and only if "V" is unassigned or assigned after a when t is false.
  5. "V" is assigned or unassigned after a||b if and only if "V" is assigned or unassigned after a||b when it is true and "V" is unassigned or assigned after a||b when it is false.

Logical complement operator(!)

  1. Suppose "V" is assigned or unassigned after "a" is false, and at last ", V" is assigned after! a.
  2. If "V" is assigned or unassigned after a when true, then "V" is assigned or unassigned after "! a"; it becomes false.
  3. "V" is unassigned or assigned before a if and only if "V" is unassigned or assigned before "! a".
  4. "V" is unassigned after "! a" if and only if "V" is unassigned or assigned after "!a" when it is true, and "V" is unassigned or assigned after "!a" when it is true.

The conditional operator (?:)

Let us assume that b and c are boolean-valued expressions.

  1. If "V" is unassigned or assigned after a? b:c is true if and only if "V" is unassigned or assigned after b when it is true and "V" is unassigned or assigned after c when it is true.
  2. When a ? b:c is false if "V" is unassigned or assigned after that expression, and it is false if and only if "V" is unassigned or assigned after b when it is false and "V" is unassigned or assigned after c when it is false.
  3. "V" is [un]assigned before a if and only if "V" is [un]assigned before a ? b:c.
  4. "V" is assigned or unassigned before b if and only if "V" is unassigned or assigned after a when true.
  5. "V" is assigned or unassigned before c if and only if "V" is unassigned or assigned after a when it becomes false.
  6. "V" is unassigned or assigned after a ? b:c if and only if "V" is unassigned or assigned after a ? b:c when it is true and "V" is unassigned after a ?? b:c when it becomes false.

Boolean type expressions

Let us assume that "e" is an expression of boolean type, not a logical complement expression, and not a boolean constant expression! a, not a conditional-and expression a&&b, not a conditional-or expression a||b, or not a conditional expression a ? b:c.

  1. "V" is unassigned or assigned after "e" when it is true if and only if "V" is unassigned or assigned after "e".
  2. "V" is unassigned or assigned after "e" when it is false if and only if "V" is unassigned or assigned after "e".

Assignment expressions

Let us consider an assignment expression a=b, a+=b, a%=b, a|=b, a^=b, a*=b, a-=b, a>>=b, a<<=b and many more.

  1. "V" has to be definitely assigned after the assignment expression if and only if "a" is "V" or "V" is definitely assigned after "b".
  2. "V" is definitely unassigned after the assignment expression if and only if a is not "V", and also", V" is definitely unassigned after b.
  3. "V" is unassigned or assigned before "a" if ad only if "V" is unassigned or assigned before the assignment expression.
  4. "V" is unassigned or assigned before "b" if and only if "V" is unassigned or assigned after a.

NOTE: If a is "V" and "V" is not definitely assigned before the compound assignment like a&=b, then a compile-time error will occur, and the first rule for definite assignment discussed will include the disjunction "a is V", and also for compound assignment expressions, it is not like a simple assignment, so that "V" is definitely assigned after points in the code.

As we include the disjunction, "a is V" will not affect the binary decision to ensure whether a program is acceptable or will result in a compile-time error. It will affect how many different points are in the code and is regarded as erroneous, so when practising, it will improve the quality of error reporting. So, a similar remark will apply to the inclusion of the conjunction "a is V" in rule one for definite unassignment, as stated above.

Operators ++ and --

  1. "V" is definitely assigned only after ++a, --a, a++, or a-- if and only if a is V or V is definitely assigned after the operand expression.
  2. "V" is definitely unassigned after ++a, --a, a++, or a-- if and only if a is not V and V is definitely unassigned after the operand expression.
  3. "V" is unassigned or assigned before a if and only if "V" is unassigned or assigned before ++a, --a, a++, or a--.

Other expressions

Let us assume that expression is not a boolean constant expression, and also not a pre-increment expression ++a, not a pre-decrement expression --a, not a post-increment a++, not a post decrement expression a--, not a logical complement expression ! a, not a conditional-and expression a&&b, not a conditional-or expression a||b, not a conditional expression a? b:c, not an assignment expression, or lambda expression, then we must follow the following rules:

Rule 1: If an expression has no sub-expressions, then "V" is unassigned or assigned after the expression if and only if "V" is unassigned or assigned before the expression.

In the above case, it will apply to literals, names, this (both qualified and unqualified), unqualified class instance creation expressions with no arguments, array creation expressions with initializers that will contain no expressions, superclass field access expressions, unqualified and type-qualified method invocation expressions with no arguments, superclass method invocation expressions with no arguments, and superclass and type-qualified method reference expressions.

Rule 2: If an expression has sub-expressions, "V" is unassigned or assigned after the expression if and only if "V" is unassigned or assigned after its rightmost immediate sub-expression.

There is a piece of subtle reasoning behind the assertion that a variable "V" can be known to be definitely unassigned after a method invocation expression. It will be taken by itself, at face value, and without qualification; such an assertion will not always true because the invoked method will perform assignments. It must remember that for the Java programming languages, the concept of the definite assignment will be applied only to final blank variables.

If "V" is a blank final local variable, then only the method to which its declaration belongs will perform assignments to "V". If "V" is a final blank field, then only a constructor or an initializer for the class containing the declaration for "V", and can perform assignments to "V". At last, explicit constructor invocations are handled specially, even though they are syntactically same to expressions that containing method invocations. They are not expression statements, and finally, the rules in this section do not apply to explicit constructor invocations.

Suppose an expression is a lambda expression, and the following rules will apply:

  1. "V" is unassigned or assigned after the expression if and only if "V" is unassigned or assigned before the expression.
  2. "V" is definitely assigned before the expression or block that is the lambda body if and only if "V" is definitely assigned before the lambda expression.

There are no rules that "V" is to be definitely unassigned before a lambda body. The variable that is definitely unassigned before the lambda body will be later assigned to it. So, we cannot examine whether the variables should be assigned when the body is executed.

For any immediate subexpression, "y" of an expression "x", where "x" is not a lambda expression, "V" is unassigned or assigned before "y" if and only if any one of the following is true.

  1. "V" is definitely assigned only after a local variable declaration statement which contains at least one variable initializer if and only if "V" is definitely set after the last variable initializer in the presence of a local variable declaration statement or the last variable initializer in the declaration in the declarator which will declare "V".
  2. "V" will definitely be unassigned after a local variable declaration statement containing at least one variable initializer if and only if "V" is unassigned after the last variable initializer in the local variable declaration statement and the last variable initializer in the declaration is not the declarator which declares "V".
  3. "V" will be unassigned before the first variable initializer in a local variable declaration statement if and only if "V" is unassigned or assigned before the local variable declaration statement.
  4. "V" is definitely assigned before any variable initializer "e" other than the first one in the local variable declaration statement if and only if "V" is definitely set only after the variable initializer to the left of "e" to the expression of the initializer to the left of "e" and is in the declarator which declares "V".
  5. "V" will assign definitely be before any of the variable initializer "e" other than the first one in the local variable declaration statement if and only if "V" is definitely unassigned only after the variable initializer to the left of "e" and is not in the declarator which will declare "V".

Labelled statements

  1. "V" will be unassigned or assigned after the labelled statement L:S, where "L" is a label if and only if "V" is unassigned or assigned only after "S", and "V" will assign before every break statement which will exist in the labelled statement L: S.
  2. "V" will unassign or assign before "S" if and only if "V" is unassigned or assigned before L: S.

Expression statement

  1. "V" will unassign or assign after the expression statement "e" if and only if it is unassigned or assigned only after "e".
  2. "V" is unassigned or assigned before "e" if and only if it is unassigned or assigned before "e".

"if" statements

There are some rules to apply for a statement if (e) S. They are:

  1. "V" is unassigned or assigned only after if (e) S if and only if "V" is unassigned or assigned after "S" and "V" is unassigned or assigned after "e" when it is false.
  2. "V" is unassigned or assigned only before "e" if and only if "V" is unassigned or assigned before if (e) S.
  3. "V" will assign or unassign before "S" if and only if "V" is unassigned or assigned after "e" when it is true.

There are some rules to apply for a statement if (e) S else T. They are:

  1. "V" is unassigned or assigned after if (e) S else T if and only if "V" is unassigned or assigned after "S" and "V" is assigned or assigned after T.
  2. "V" is unassigned or assigned before "e" if and only if "V" is unassigned or assigned before if (e) S else T.
  3. "V" is unassigned or assigned before "S" if and only if "V" is unassigned or assigned "e" when it is true.
  4. "V" is unassigned or assigned before T if and only if "V" is unassigned or assigned after "e" when it is false.

Assert statement

There are some rules to apply to both a statement assert e1 and to the statement assert e1: e2.

  1. "V" will be unassigned or assigned before e1 if and only if "V" is unassigned or assigned before the assert statement.
  2. "V" is definitely assigned or unassigned after the assert statement if and only if "V" is definitely assigned before the assert statement.
  3. "V" is definitely unassigned after the assert statement if and only if "V" is definitely unassigned before the assert statement and "V" is definitely unassigned after e1 when it is true.

There is a rule to apply for a statement asserting e1: e2. That is:

  1. "V" is unassigned or assigned before e2 if and only if "V" is unassigned or assigned after e1 when it is false.

Switch statements

"V" will assign or unassign only after a switch statement if and only if all of the below statements are true:

  1. Either there is a default label in the switch block, or "V" is unassigned or assigned after the switch expression.
  2. Either there are no switch labels in the switch block that will not begin a block statement group, that is, there are no switch labels following before the closed curly braces "}" which will end the switch block, or "V" is unassigned or assigned after the switch expression.






Youtube For Videos Join Our Youtube Channel: Join Now

Feedback


Help Others, Please Share

facebook twitter pinterest

Learn Latest Tutorials


Preparation


Trending Technologies


B.Tech / MCA