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.
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:
In the case of Boolean-valued expressions, the last two steps in the above are redirected into four points:
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.
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:
Let us take an example.
The above statement is understood by two rules given below:
Definite assignment and expressions
Boolean constant expressions
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 (&&)
Conditional-Or operator (||)
Logical complement operator(!)
The conditional operator (?:)
Let us assume that b and c are boolean-valued expressions.
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.
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.
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 --
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:
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.
There are some rules to apply for a statement if (e) S. They are:
There are some rules to apply for a statement if (e) S else T. They are:
There are some rules to apply to both a statement assert e1 and to the statement assert e1: e2.
There is a rule to apply for a statement asserting e1: e2. That is:
"V" will assign or unassign only after a switch statement if and only if all of the below statements are true: