Friday, January 13, 2023

Quiz yourself: Understanding the syntax of Java’s increment and decrement operators

Java’s increment and decrement operators, Oracle Java Career, Java Skills, Java Jobs, Java Tutorial and Materials, Oracle Java Preparation, Oracle Java Guides

Do Java expressions such as ii[++i] = 0, ii[i++]++, or i = +(i--) give you a headache?


Given the following Calc class

class Calc {
    Integer i;
    final int[] ii = {0};
    {
        ii[++i] = 0; // line 1
        i--;         // line 2
        ii[i++]++;   // line 3
        (i--)--;     // line 4
        i = +(i--);  // line 5
    }
}

Which statement is correct? Choose one.

A. Compilation fails at line 1 only.

B. Compilation fails at line 2 only.

C. Compilation fails at line 3 only.

D. Compilation fails at line 4 only.

E. Compilation fails at line 5 only.

F. Compilation fails at more than one line.

G. All lines compile successfully.

Answer. This question tests your knowledge of syntax for a variety of expressions.

First, notice there are two object field variables.

◉ The first is an uninitialized field of Integer type, called i. Because this is an uninitialized object field, it would have a null value when it is initialized. However, the compiler does not care about this; from that perspective, it’s simply a variable and the lack of explicit initialization is irrelevant.

◉ The second field is an int array called ii. This field is marked final and is initialized with an array literal containing a single element having a value of zero. It’s important to remember that marking the field as final merely means the field can never be modified to refer to any other array. It does not prevent the elements of the array from being changed (though it’s also true that you can never grow or shrink an array in Java).

Java’s increment and decrement operators, Oracle Java Career, Java Skills, Java Jobs, Java Tutorial and Materials, Oracle Java Preparation, Oracle Java Guides
Next, consider the increment and decrement operator usage. It might cause some concern that these are applied to the variable i, which is of Integer type. After all, Integer objects are immutable. However, this is not a problem. All that happens is that the contents of the variable are unboxed, the resulting int is incremented or decremented, and then a new Integer is created with that new value. Finally, the reference to the new Integer is assigned to the variable.

Look at line 1 considering the information above. The effect would be to assign zero to an element of the array at a subscript one greater than the int value of i before executing the line. A second effect would be that the int value in the object referred to by i would now be one greater than before. This is all valid syntax, even though the code couldn’t run correctly, because it would fail with a NullPointerException. However, the question doesn’t ask about running the code, only about compiling it. Also note that under some conditions, code of this kind could fail at runtime with an ArrayIndexOutOfBoundsException. Again, this is not relevant in this question. From this, you can see that line 1 compiles correctly.

A similar analysis of line 2 reveals that if i were not null, this line would reassign the variable i to refer to a new Integer object with an int value one less than the Integer to which it previously referred. Even though the code of line 2 would not execute, it would compile correctly.

In line 3, the code would increment the array element at the index value indicated by the current value of i, and then reassign i to have an int value one greater than before. This would fail with a NullPointerException, and if that were rectified, the code might still fail if the subscript indicated by i were invalid. However, the code of line 3 is syntactically valid and would compile without error.

Line 4 would fail to compile. One of the requirements for using the increment and decrement operators is that the target of such an operator must be in storage that can be updated. Such a value is sometimes referred to as an l-value, meaning an expression that can be on the left side of an assignment. In line 4, the expression is (i--)-- and the problem is that while i-- is valid in itself, the resulting expression is simply the numeric value that is contained in the object to which i now refers. And, in the same way that you cannot write 3++ (where would you store the result?), you cannot increment or decrement such a simple expression. The parenthetical (i--) cannot store the result. Consequently line 4 is syntactically invalid and would not compile.

Line 5 is syntactically valid. If i were not null, that line would reassign i to an Integer representing one less than the previous object it referred to, then apply the (no-effect) unary plus operator, and then assign that same result to the value i. The latter two operations have no meaningful effect, but they are syntactically valid, and line 5 would compile without problems.

In light of the foregoing discussions, you can see that option D is correct, and options A, B, C, E, F, and G are all incorrect.

Conclusion. The correct answer is option D.

Source: oracle.com

Related Posts

0 comments:

Post a Comment