| No. | Answer | Remark | |
|---|---|---|---|
| 1 | f | Prints: fffffffe,ffffffff,7fffffff | If the left-hand operand of a shift operator, <<, >> and >>>, is of type int, then the shift distance is always within the range of 0 to 31, inclusive; and is specified by the least significant 5 bits of the right hand operand. Similarly, if the left-hand operand of a shift operator is of type long, then the shift distance is always within the range of 0 to 63, inclusive; and is specified by the least significant 6 bits of the right hand operand. The left shift operator, <<, shifts each bit of the left operand to the left a distance specified by the shift distance. A number of bits that is equal to the shift distance are shifted out of the left-most bit position and are lost. A number of bits that is equal to the shift distance are shifted in at the right. The signed right shift operator, >>, shifts each bit of the left operand to the right a distance specified by the shift distance. A number of bits that is equal to the shift distance are shifted out of the right-most bit position and are lost. A number of bits that is equal to the shift distance are shifted in at the left. The value of each bit that is shifted in at the left is equal to the value of the sign bit. The signed right shift operator maintains the sign of the left operand. The unsigned right shift operator, >>>, is similar to the signed right shift operator except for the fact that each bit shifted in at the left is zero. |
| 2 | c d | 3 4 | This question demonstrates a variety of assignment conversions. The compiler will implicitly do a narrowing conversion for an assignment statement if the right hand operand is a compile time constant of type byte, short, char, or int and the value falls within the range of the variable on the left and if the variable on the left is of type byte, short, or char. In this case, variables s1 and c1 are not compile time constants so the compiler will not do an implicit narrowing conversion. However, variables s2 and c2 are compile time constants that fall within the range of the left hand operand. For more information, please see JLS section 5.2. |
| 3 | d | Prints: true,true | The bitwise complement operator produces the same result as changing the sign and subtracting one. Please note that the operand must be an integral type. The bitwise complement operator can not be applied to a floating-point value. |
| 4 | b | Prints: 2,true | Suppose the left operand were divided by the right operand. The remainder operator returns the remainder of the division operation. For integral types, the identity, (y == ((y/x)*x+(y%x))), is always true. |
| 5 | j | Compile-time error | The type of the reference, color2, is Red. Since Red is not a subclass or a superclass of Blue, the expression, color2 instanceof Red, is rejected at compile-time. Please note: The expression, x instanceof T, produces a compile-time error whenever the cast expression, (T)x, produces a compile-time error. The type of the reference, color1, is Color. Therefore the expression, color1 instanceof Color, is accepted at compile-time. The type of the object is Red. Since Red is a subclass of Color, the expression, color1 instanceof Color, is true at run-time. The type of the reference, color1, is Color. Since Color is a superclass of Blue, the expression, color1 instanceof Color, is accepted at compile-time. The type of the object instance referenced by color1 is Blue. Since Blue is not the class Red or a subclass of Red, the expression, color1 instanceof Red, is false at run-time. |
| 6 | f | Prints: 3,0,3 | Java evaluates operands from left to right while respecting operator precedence. The order of operator precedence starting with the lowest is as follows: |, ^, &. Although complete memorization of the operator precedence chart is not necessary, it is a good idea to memorize the three levels that appear in this question. |
| 7 | g | Prints: fffffffe,fffffffe | For each of the three shift operators, <<, >> and >>>, the shift distance is specified by the right hand operand. If the left operand is of type int, then the shift distance is always within the range 0 to 31, inclusive; and the following expression is always true: (int1 << shift) == (int1 << (shift & 0x1f)). The hexadecimal representation of decimal 31 is 0x1f and the binary representation is 0001 1111. The hexadecimal representation of decimal 33 is 0x21 and the binary representation is 0010 0001. The expression i1 << (33 & 0x1f) is equivalent to (0xffffffff << (0x21 & 0x1f)). Evaluation of the right hand operand of the shift operator produces (0xffffffff << 1). The final result is 0xfffffffe. Similarly, if the left operand is of type long, then the shift distance is always within the range 0 to 63, inclusive; and the following expression is always true: (long1 << shift) == (long1 << (shift & 0x3f)). |
| 8 | d | Prints: GFC206,GFC206 | Type GFC207 is a subclass of types GFC206 and GFC205, so any of the four methods are applicable to the method invocation expression, m(gfc207, gfc207). The most specific of the four, m(GFC206 x, GFC206 y), is chosen. Type GFC206 is a subclass of type GFC205, and method m(GFC206 x, GFC206 y) is more specific than the other three, because any invocation of m(GFC206 x, GFC206 y) could also be handled by any of the other three without causing a compile-time type error. |
| 9 | f | Compile-time error | The method invocation expression, m(gfc213, gfc213), is ambiguous; because, no applicable method is more specific than all of the others. Method m(GFC212 x, GFC212 y) is more specific than m(GFC212 x, GFC211 y), because any invocation of m(GFC212 x, GFC212 y) could also be handled by m(GFC212 x, GFC211 y) without causing a compile-time type error. However, some invocations of m(GFC212 x, GFC212 y) can not be handled by m(GFC211 x, GFC213 y), so m(GFC212 x, GFC212 y) is not more specific than m(GFC211 x, GFC213 y). Furthermore, not all invocations of m(GFC211 x, GFC213 y) could be handled by m(GFC212 x, GFC212 y). |
| 10 | f | Prints: true,false,true | The left operand of the instanceof operator must be null or a reference to an instance of an Object or a subclass of Object. The right operand of the instanceof operator must be a class type, interface type or array type. If the left operand is a reference to an instance of the type specified by the right operand or if the left operand is a reference to an instance of a subclass of the type specified by the right operand, then instanceof returns true. |
| 11 | b | Prints: byte byte boolean | Variable b1 was initialized by the first method invocation statement, so the second method invocation statement does not result in a compile-time error. The assignment expression, b1 = 1, initializes variable b1 with the value 1, and the same value is passed as an argument to method m1(byte b1). The method invocation expression, m1(b1), invokes the same method, m1(byte b1). The argument of the third method invocation expression, m1(b1 == 1), is the result of the equality expression, b1 == 1. The type of the result and the argument is boolean, so the invoked method is m1(boolean b1). |
| 12 | d | Prints: 3,1 | Inside of method m2, the local variables i1 and i2 remain unchanged while the shadowed instance variables are changed. |
| 13 | c | Prints: 3 | The expression can be simplified as follows: j = 1 + ((2 * 3) % 4) + 5 = 8. The original expression is as follows: j = ++i + ((++i * ++i) % ++i) + ++i;. Step one. Evaluate the unary expressions from left to right: j = 1 + ((2 * 3) % 4) + 5. Step two. Evaluate the inner-most parentheses: j = 1 + (6 % 4) + 5. Step three: Evaluate the inner-most parentheses. j = 1 + 2 + 5. Step four: Work through the expression from left to right. j = 8. The argument of the print expression is: j%5. The result is: 8 % 5 = 3. |
| 14 | b | Prints: BBABBA | Type B is a subclass of type A, and method m(B x, B y) is more specific than the other three; because any invocation of it could be handled by any of the other three without causing a compile-time type error. All four methods are applicable to the first method invocation expression, m(null,null). The most specific method, m(B x, B y), is chosen; and both arguments are converted to type B. In the second method invocation expression, m(a1=null,b1=null), simple assignment expressions initialize the local variables a1 and b1 with null references of types A and B respectively. The invoked method is m(A x, B y). In the third method invocation expression, the positions of the arguments are reversed relative to the previous invocation: The type of the first argument is now B and the second is A. The invoked method is m(B x, A y). |
| 15 | c | Prints: m3Cm2Bm1A | The method invocation expression, m3(new C()), invokes method m3(C x), because the argument type matches the parameter type of the method declaration exactly. Method m3 uses the parameter as the argument of the next invocation expression, m2(x). Of the two overloaded versions of m2, the most specific is invoked, m2(B x). Type B is a subclass of A, so any invocation of m2(B x) could be handled by m2(A x) without causing a compile-time type error. For that reason, m2(B x) is more specific than m2(A x). |
| 16 | b | Prints: FFT | The expression used to assign variable b1 is equivalent to the expression used to assign variable b2. The results demonstrate that the conditional operator (?:) groups from right-to-left. |
| 17 | c | Prints: Blue,Blue | The expression used to assign variable b1 is equivalent to the expression used to assign variable b2. The results demonstrate that the conditional operator (?:) groups from right-to-left. |
| 18 | g | None of the above | Prints 31,0. The expression (-1 & 0x1f) is equal to (0xffffffff & 0x1f), and both are equal to the hex value 0x1f or decimal 31. The expression (8 << -1) is equivalent to (8 << 0xffffffff). If the left hand operand of a shift expression is of type int, then the right hand operand is implicitly masked with the value 0x1f. In other words, the expression (8 << -1) is equivalent to (8 << (-1 & 0x1f)). By replacing -1 with the hexadecimal representation we have (8 << (0xffffffff & 0x1f)). By evaluating the right hand operand we have (8 << 31). When 8 is shifted 31 bits to the left, the result is zero since the only non-zero bit is lost as it is shifted beyond the most significant bit of the int data type. |