| No. | Answer | Remark | |
|---|---|---|---|
| 1 | b | Prints: 1,2 | Primitive arguments are passed by value. The method m1 increments the parameter x, and the result is returned. The local variable x of main remains unchanged. |
| 2 | b | Prints: BCD | The index for the first element of an array is zero so the first argument printed by this program is the second argument on the command line following the name of the class. |
| 3 | j | Compile-time error | Both operands of the conditional and operator and the conditional or operator must be of type boolean. |
| 4 | f g h | 6 7 8 | 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 is of type byte, short, or char. |
| 5 | e | Prints: true,false,false | The conditional and expression is not evaluated, because the left hand operand of the conditional or expression is true. The original expression is as follows: x = (a = true) || (b = true) && (c = true). The left hand operand of the conditional or expression is the result of the assignment expression, (a = true). Since the left hand operand of the conditional or expression is true, the right hand operand will not be evaluated. In this case, the right hand operand is the conditional and expression. Consequently, neither operand of the conditional and expression is evaluated and the variables, b and c, maintain their default values of false. |
| 6 | b c f | 2 3 6 | The maximum value of type byte is 127. The minimum value of type short is -32768. The maximum value of type char is 65535. |
| 7 | b | Prints: 1, 2, 3, 4, 11, | The expression can be simplified as follows: j = 1 - 2 + 3 * 4 = 11. The original expression is as follows: m(m(1) - m(2) + m(3) * m(4)). Simplification step one. Evaluate each operand from left to right: m(1 - 2 + 3 * 4). Step two. Add parentheses to indicate operator precedence: m(1 - 2 + (3 * 4)). Step three. Evaluate the inner-most parentheses: m(1 - 2 + 12). Step four: Work through the expression from left to right. j = 11. |
| 8 | d | Prints: 127 -128 -1 0 | Bytes are stored as 8 bit two's complement signed integers. When an int primitive is cast to a byte, the three most significant bytes are discarded and only the least significant byte remains. The most significant bit of the remaining byte becomes the new sign bit. byte a = (byte)127; // 01111111. byte b = (byte)128; // 10000000. byte c = (byte)255; // 11111111. byte d = (byte)256; // 00000000. |
| 9 | e | None of the above | Line 4 does not generate a compile-time error. The reference named base actually refers to an instance of type Sub, so the reference may be cast to type Sub. |
| 10 | g | None of the above | The null literal is converted to an int array type with the value null. All array types implement the Cloneable interface, so any array reference can be assigned to a reference of type Cloneable. The int array object referenced by the Cloneable reference, c, can be assigned to a reference of the int array type, int[]. |
| 11 | a | Prints: float,float | A method invocation conversion can widen an argument of type float to match a method parameter of type double, so any argument that can be passed to m(float i) can also be passed to m(double i) without generating a compile-time type error. For that reason, we can say that m(float i) is more specific than m(double i). Since both methods are applicable, the more specific of the two, m(float i), is chosen over the less specific, m(double i). The arguments of the method invocation expressions, m(a1) and m(b1), are of types int and long respectively. A method invocation conversion can widen an argument of type int or long to match either of the two method parameter types float or double; so both methods, m(float i) and m(double i), are applicable to the two method invocation expressions. Since both methods are applicable, the more specific of the two, m(float i) is chosen rather than the less specific, m(double i). |
| 12 | c | Prints: 1, 2, 3, 4, 9, | The expression can be simplified as follows: 1 + 2 % 3 * 4 = 9. The original expression is as follows: m(m(1) + m(2) % m(3) * m(4)). Simplification step one. Evaluate each operand from left to right: m(1 + 2 % 3 * 4). Step two. Add parentheses to indicate operator precedence and associativity: m(1 + ((2 % 3) * 4). Step three. Evaluate the inner-most parentheses: m(1 + (2 * 4)). Step four. Evaluate the inner-most parentheses: m(1 + 8). The result is 9. |
| 13 | c | 3 | Short is signed and char is not signed so an explicit cast is necessary when a short is assigned to a char and vice versa. |
| 14 | d | Run-time error at line 2 | The compiler accepts the explicit cast at line 2, but an error is generated at run-time. Type Base is the super class of type Sub, so an instance of type Base can not be converted to the type of the subclass, Sub. |
| 15 | e | Compile-time error at line 3. | Although the referenced object is indeed an array of type int, an explicit cast is necessary to cast the obj reference to an int array. |
| 16 | a | Prints: float,float | A method invocation conversion can widen an argument of type float to match a method parameter of type double, so any argument that can be passed to m(float i) without generating a compile-time type error can also be passed to m(double i). For that reason, we can say that m(float i) is more specific than m(double i). The arguments of the method invocation expressions, m(a1) and m(b1), are of types char and long respectively. A method invocation conversion can widen an argument of type char or long to match either of the two method parameter types float or double; so both methods, m(float i) and m(double i), are applicable to the two method invocation expressions. Since both methods are applicable, the more specific of the two, m(float i) is chosen rather than the less specific, m(double i). |
| 17 | d | Prints: 2, 2, -3, 3, 4, | The expression can be simplified as follows: j = 2 + 2 + -3 + 3 = 4. The original expression is as follows: j = ++i + i++ + -i + i++. Simplification step one. Evaluate the unary expressions from left to right: j = 2 + 2 + -3 + 3. Step two. Complete the evaluation of the simplified expression: j = 4. |
| 18 | c | Prints: Bird,Cat | Although the reference variable r2 is assigned the value of reference variable r1 in method m1, the reference pet2 remains unchanged in the main method. Object references are passed by value: the invoked method gets a copy of the object reference. The reference parameter r1 can be used to modify the state of the instance referenced by pet1, but r2 can not be used to force pet2 to reference a different instance. |
| 19 | b | Prints: 1,2,3,4,1 | The expression can be simplified as follows: j = 1 + (2 * 3) + 4 = 11. The original expression is as follows: j = m(i++) + m(i++) * m(i++) + m(i++). The method, m, prints and then returns the value of the parameter, so the original expression is equivalent to the following: j = i++ + i++ * i++ + i++. Step one. Work through the expression from left to right to evaluate the unary expressions: j = 1 + 2 * 3 + 4. Step two. Add parentheses to indicate operator precedence: j = 1 + (2 * 3) + 4. Step three. Work through the simplified expression: j = 1 + 6 + 4 = 11. Step four. Evaluate the expression that is the argument of the print method: j % 5 = 11 % 5 = 1. |