Answers Of Review Of Java LanguageThis is a featured page

Answers Of Review Of Java Language

1 Basics of Java Programming

1.1
(d)
A method is an operation defining the behavior for a particular abstraction. Java implements abstractions, using classes that have properties and behavior. Behavior is dictated by the operations of the abstraction.
1.2
(b)
An object is an instance of a class. Objects are created from class definitions that implement abstractions. The objects that are created are concrete realizations of those abstractions.
1.3
(b)
The code marked with (2) is a constructor. A constructor in Java is declared like a method, except that the name is identical to the class name and it does not specify a return value.
1.4
(b) and (f)
Two objects and three reference variables are created by the code. Objects are typically created by using the new operator. Declaration of a reference variable creates a variable regardless of whether a reference value is assigned to it or not.
1.5
(d)
An instance member is a field or an instance method. These members belong to an instance of the class rather than the class as a whole. Members which are not explicitly declared static in a class definition are instance members.
1.6
(c)
An object can pass a message to another object by calling an instance method of the other object.
1.7
(d) and (f)
Given the declaration class B extends A {...} we can conclude that class B extends class A, class A is the superclass of class B, class B is a subclass of class A, and class B inherits from class A, which means that objects of class B will inherit the field value1 from class A.
1.8
(d)
The compiler supplied with the Java 2 SDK is named javac. It requires the names of the source files that should be compiled.
1.9
(a)
Java programs are executed by the Java Virtual Machine (JVM). In the Java 2 SDK, the command java is used to start the execution by the JVM. The java command requires the name of a class that has a valid main() method. The JVM starts the program execution by calling the main() method of the given class. The exact name of the class should be specified, and not the name of the class file, that is, the ".class" extension in the class file name should not be specified.


Language Fundamental
2.1
(c)52pickup is not a legal identifier. The first character of an identifier cannot be a digit.
2.2
(e)In Java, the identifiers delete, thrown, exit, unsigned, and next are not keywords. Java has a goto keyword, but it is reserved and not currently used.
2.3
(b)It is a completely valid comment. Comments do not nest. Everything from the start marker of a comment block (/*) until the first occurrence of the end marker of the comment block (*/) is ignored by the compiler.
2.4
(a) and (d)
String is a class, and "hello" and "t" denote String objects. Java only has the following primitive data types: boolean, byte, short, char, int, long, float, and double.
2.5
(a), (c), and (e)
Type (a) is a boolean data type, while types (c) and (e) are floating-point data types.
2.6
(c)
The bit representation of int is 32-bits wide and can hold values in the range –231 through 231–1.
2.7
(a), (c), and (d)
The \uxxxx notation can be used anywhere in the source to represent unicode characters.
2.8
(c)
Local variable a is declared but not initialized. The first line of code declares the local variables a and b. The second line of code initializes the local variable b. Local variable a remains uninitialized.
2.9
(c)
The local variable of type float will remain uninitialized. Fields receive a default value unless explicitly initialized. Local variables remain uninitialized unless explicitly initialized. The type of the variable does not affect whether a variable is initialized or not.
2.10
(c)
The class will fail to compile since the package declaration can never occur after an import statement. The package and import statements, if present, must always precede any class definitions. If a file contains both import statements and a package statement, then the package statement must occur before the import statements.
2.11
true
Although nonsensical, an empty file is a valid source file. A source file can contain an optional package declaration, any number of import statements, and any number of class and interface definitions.
2.12
(d) and (f)
The main() method must be declared public, static, and void and takes a single array of String objects as argument. The order of the static and public keywords is irrelevant. Also, declaring the method final is irrelevant in this respect.
2.13
(a), (b), and (c)
Neither main, string, nor args are reserved keywords, but they are legal identifiers. In the declaration public static void main(String[] args), the identifier main denotes the method that is the main entry point of a program. In all other contexts, the identifier main has no predefined meaning.

Operator & Assinment
3.1
(a)
A value of type char can be assigned to a variable of type int. An implicit widening conversion will convert the value to an int.
3.2
(d)
An assignment statement is an expression statement. The value of the expression statement is the value of the expression on the right hand side. Since the assignment operator is right associative, the statement a = b = c = 20 is evaluated as follows: (a = (b = (c = 20))). This results in the value 20 being assigned to variable c, then the same value being assigned to variable b and finally to variable a. The program will compile correctly and display 20 when run.
3.3
(c)
Strings are objects. The variables a, b, and c are references that can denote such objects. Assigning to a reference only changes the reference value. It does not create a copy of the source object or change the object denoted by the old reference value in the destination reference. In other words, assignment to references only affects which object the destination reference denotes. The reference value of the "cat" object is first assigned to variable a, then to variable b, and later to variable c. The program prints the string denoted by the variable c, which is "cat".
3.4
(a), (d), and (e)
A binary expression with any floating-point operand will be evaluated using floating-point arithmetic. Expressions such as 2/3, where both operands are integers, will use integer arithmetic and evaluate to an integer value.
3.5
(b)
The / operator has higher precedence than the + operator. This means that the expression is evaluated as ((1/2) + (3/2) + 0.1). The associativity of the binary operators is from left to right, giving (((1/2) + (3/2)) + 0.1). Integer division results in ((0 + 1) + 0.1) which evaluates to 1.1.
3.6
(d)
0x10 is a hexadecimal literal equivalent to the decimal value 16. 10 is a decimal literal. 010 is an octal literal equivalent to the decimal value 8. The println() method will print the sum of these values, which is 34, in decimal form.
3.7
(b), (c), and (f)
The unary + and - operators with right-to-left associativity are used in the valid expressions (b), (c), and (f). Expression (a) tries to use a nonexistent unary - operator with left-to-right associativity, expression (d) tries to use a decrement operator (--) on an expression that does not resolve to a variable, and expression (e) tries to use a nonexistent unary * operator.
3.8
(b)
The expression evaluates to –6. The whole expression is evaluated as (((-(-1)) - ((3 * 10) / 5)) - 1) according to the precedence and associativity rules.
3.9
(a), (b), (d), and (e)
In (a) the conditions for implicit narrowing conversion are fulfilled: the source is a constant expression of type int, the destination type is of type short, the value of the source (12) is in the range of the destination type. The assignments in (b), (d), and (e) are valid, since the source type is narrower than the target type and an implicit widening conversion will be applied. The expression (c) is not valid. Values of type boolean cannot be converted to other types.
3.10
(a), (c), and (d)
The left associativity of the + operator makes the evaluation of (1 + 2 + "3") proceed as follows: (1 + 2) + "3" 3 + "3" "33". Evaluation of the expression ("1" + 2 + 3), however, will proceed as follows: ("1" + 2) + 3 "12" + 3 "123". (4 + 1.0f) evaluates as 4.0f + 1.0f 5.0f and (10/9) performs integer division, resulting in the value 1. The operand 'a' in the expression ('a' + 1) will be promoted to int, and the resulting value will be of type int.
3.11
(d)
The expression ++k + k++ + + k is evaluated as ((++k) + (k++)) + (+k) ((2) + (2) + (3)), resulting in the value 7.
3.12
(d)
The types char and int are both integral. A char value can be assigned to an int variable since the int type is wider than the char type and an implicit widening conversion will be done. An int type cannot be assigned to a char variable because the char type is narrower than the int type. The compiler will report an error about a possible loss of precision in the line labeled (4).
3.13
(c)
Variables of type byte can store values in the range –128 to 127. The expression on the right-hand side of the first assignment is the int literal 128. Had this literal been in the range of the byte type, an implicit narrowing conversion would have to be applied during assignment to convert it to a byte value. Since 128 is outside the valid range of type byte, the compiler will not compile the code.
3.14
(a)
First, the expression ++i is evaluated, resulting in the value 2, Now the variable i also has the value 2. The target of the assignment is now determined to be the element array[2]. Evaluation of the right-hand expression, --i, results in the value 1. The variable i now has the value 1. The value of the right-hand expression 1 is then assigned to the array element array[2], resulting in the array contents to become {4, 8, 1}. The program sums these values and prints 13.
3.15
(a) and (c)
The expression (4 <= 4) is true. The null literal can be compared, so (null != null) yields false.
3.16
(c) and (e)
The remainder operator is not limited to integral values, but can also be applied to floating-point operands. Identifiers in Java are case sensitive. Operators *, /, and % have the same level of precedence. Type short has the range -32768 to +32767 inclusive. (+15) is a legal expression using the unary + operator.
3.17
(a), (c), and (e)
The != and ^ operators, when used on boolean operands, will return true if and only if one operand is true, and false otherwise. This means that d and e in the program will always be assigned the same value, given any combination of truth values in a and b. The program will, therefore, print true four times.
3.18
(b)
The element referenced by a[i] is determined based on the current value of i, which is zero, that is, the element a[0]. The expression i = 9 will evaluate to the value 9, which will be assigned to the variable i. The value 9 is also assigned to the array element a[0]. After the execution of the statement, the variable i will contain the value 9, and the array a will contain the values 9 and 6. The program will print 9 9 6 when run.
3.19
(c) and (d)
Unlike the & and | operators, the && and || operators short-circuit the evaluation of their operands if the result of the operation can be determined from the value of the first operand. The second operand of the || operator in the program is never evaluated because of short-circuiting. All the operands of the other operators are evaluated. Variable i ends up with a value of 3, which is the first digit printed, and j ends up with a value of 1, which is the second digit printed.
3.20
(b) and (f)
The method test() will print out its second argument if the results of performing a signed and an unsigned 1-bit right shift on its first argument differ. The only difference between these operations is that when performing a signed shift, the leftmost bit will retain its state, rather than being assigned the bit value 0. The operational difference will, therefore, only be apparent when applied on values where the value of the leftmost bit is 1. Of the values being passed to the method test(), only the result of the expression 1<<31 (i.e., 1000 ... 0000) and the value -1 (1111 ... 1111) have the left-most bit set.
3.21
(b) and (g)
Java has the operators >> and >>> to perform signed and unsigned right shifts. For left shifts there is no difference between shifting signed and unsigned values. Java, therefore, only has one left-shift operator, which is <<. <<< is not an operator in Java. Java has the boolean AND compound assignment operator &=, but &&= is not an operator in Java.
3.22
(b), (c), (d), and (e)
All the expressions will return the same result. All expressions will accommodate negative values, and x can be any value of type int. However, expression (a) will not assign the result back to the variable x.
3.23
(a), (c), and (d)
The logical complement operator (!) cannot be used as an integer bitwise operator, and the bitwise complement operator (~) cannot be used as a boolean logical operator.
3.24
(b), (c), and (e)
All the values of the expressions on the right-hand side of the assignments are implicitly promoted to type int. For expression (b) this works, since the target type is also int. The compound assignment operators in expressions (c) and (e) ensure that an implicit narrowing conversion makes the result fit back in the target variable. Expressions (a) and (d) are simply invalid, since the type of expression on the right-hand side of the assignment operator is not compatible with the type of the target variable on the left-hand side.
3.25
(b)
Evaluation of the actual parameter i++ yields 0, and increments i to 1 in the process. The value 0 is copied into the formal parameter i of the method addTwo() during method invocation. However, the formal parameter is local to the method, and changing its value does not affect the value in the actual parameter. The value of variable i in the main() method remains 1.
3.26
(d)
The variables a and b are local variables that contain primitive values. When these variables are passed as parameters to another method, the method receives copies of the primitive values in the variables. The original variables are unaffected by operations performed on the copies of the primitive values within the called method. The variable bArr contains a reference value that denotes an array object containing primitive values. When the variable is passed as a parameter to another method, the method receives a copy of the reference value. Using this reference value, the method can manipulate the object that the reference value denotes. This allows the elements in the array object referenced by bArr to be accessed and modified in the method inc2().
3.27
(d)
The length of the array passed to the main() method corresponds exactly to the number of command-line arguments given to the program. Unlike some other programming languages, the element at index 0 does not contain the name of the program. The first argument given is retrieved using args[0], and the last argument given is retrieved using args[args.length-1].
3.28
(a) and (f)
Values can only be assigned once to final variables. A final formal parameter is assigned the value of the actual parameter at method invocation. Within the method body, it is illegal to reassign or modify the value of a final parameter. This causes a++ and c = d to fail. Whether the actual parameter is final does not constrain the client that invoked the method, since the actual parameter values are copied to the formal parameters.


Declarations and Access Control
4.1
(d)
In Java, arrays are objects. Each array object has a final field named length that stores the size of the array.
4.2
(a)
Java allows arrays of length zero. Such an array is passed as an argument to the main() method when a Java program is run without any program arguments.
4.3
(c)
The [] notation can be placed both before and after the variable name in an array declaration. Multidimensional arrays are created by constructing arrays that can contain references to other arrays. The expression new int[4][] will create an array of length 4, which can contain references to arrays of int values. The expression new int[4][4] will create the same array, but will in addition create four more arrays, each containing four int values. References to each of these arrays are stored in the first array. The expression int[][4] will not work, because the arrays for the dimensions must be created from left to right.
4.4
(b) and (e)
The size of the array cannot be specified as in (b) and (e). The size of the array is given implicitly by the initialization code. The size of the array is never specified in the declaration of an array reference. The size of an array is always associated with the array instance, not the array reference.
4.5
(e)
The array declaration is valid and will declare and initialize an array of length 20 containing int values. All the values of the array are initialized to their default value of 0. The for loop will print all the values in the array, that is, it will print 0 twenty times.
4.6
(e)
The program will type "no arguments" and "four arguments" when called with 0 and 3 arguments, respectively. When the program is called with no arguments, the args array will be of length zero. The program will in this case type "no arguments". When the program is called with three arguments, the args array will have length 3. Using the index 3 on the numbers array will retrieve the string "four", because the start index is 0.
4.7
(d)
The program will print "0 false 0 null" when run. All the instance variables, including the array element, will be initialized to their default values. When concatenated with a string, the values are converted to their string representation. Notice that the null pointer is converted to the string "null" rather than throwing a NullPointerException.
4.8
(b)
Only (b) is a valid method declaration. Methods must specify a return type or are declared void. This makes (d) and (e) invalid. Methods must specify a list of zero or more comma-separated parameters delimited by ( ). The keyword void is not a valid type for a parameter. This makes (a) and (c) invalid.
4.9
(a), (b), and (e)
Non-static methods have an implicit this object reference. The this reference cannot be changed, as shown in (c). The this reference can be used in a non-static context to refer to both instance and static members. However, it cannot be used to refer to local variables, as shown in (d).
4.10
(a) and (d)
The first and the third pairs of methods will compile correctly. The second pair of methods will not compile correctly, since their method signatures do not differ. The compiler has no way of differentiating between the two methods. Note that return type and the names of the parameters are not a part of the method signatures. Both methods in the first pair are named fly and, therefore, overload this method name. The methods in pair three do not overload the method name glide, since only one method has that name. The method named Glide is distinct from the method named glide, as identifiers in Java are case sensitive.
4.11
(a)
A constructor cannot specify any return type, not even void. A constructor cannot be final, static or abstract.
4.12
(b) and (e)
A constructor can be declared private, but this means that this constructor can only be used within the class. Constructors need not initialize all the fields of the class. A field will be assigned a default value if not explicitly initialized. A constructor is non-static, and as such it can directly access both the static and non-static members of the class.
4.13
(c)
A compilation error will occur at (3), since the class does not have a constructor accepting a single argument of type int. The declaration at (1) declares a method, not a constructor, since it is declared as void. The method happens to have the same name as the class, but that is irrelevant. The class has an implicit default constructor since the class contains no constructor declarations. This constructor is invoked to create a MyClass object at (2).
4.14
(c) and (d)
A class or interface name can be referred to by using either its fully qualified name or its simple name. Using the fully qualified name will always work, but in order to use the simple name it has to be imported. By importing net.basemaster.* all the type names from the package net.basemaster will be imported and can now be referred to using simple names. Importing net.* will not import the subpackage basemaster.
4.15
(c)
A class is uninstantiable if the class is declared abstract. The declaration of an abstract method cannot provide an implementation. The declaration of a non-abstract method must provide an implementation. If any method in a class is declared abstract, then the class must be declared abstract. Definition (d) is not valid since it omits the class keyword.
4.16
(e)
A class can be extended unless it is declared final. For classes, final means it cannot be extended, while for methods, final means it cannot be overridden in a subclass. A nested static class, (d), can be extended. A private member class, (f), can also be extended. The keyword native can only be used for methods, not for classes and fields.
4.17
(b) and (d)
Outside the package, member j is accessible to any class, whereas member k is only accessible to subclasses of MyClass.
Field i has package accessibility and is only accessible by classes inside the package. Field j has public accessibility and is accessible from anywhere. Field k has protected accessibility and is accessible from any class inside the package and from subclasses anywhere. Field l has private accessibility and is only accessible within its own class.
4.18
(c)
The default accessibility for members is more restrictive than protected accessibility, but less restrictive than private. Members with default accessibility are only accessible within the class itself and from classes in the same package. Protected members are in addition accessible from subclasses anywhere. Members with private accessibility are only accessible within the class itself.
4.19
(b)
A private member is only accessible by code from within the class of the member. If no accessibility modifier has been specified, a member has default accessibility, also known as package accessibility. The keyword default is not an accessibility modifier, and its only use is as a label in a switch statement. Members with package accessibility are only accessible from classes in the same package. Subclasses outside the package cannot access members with default accessibility.
4.20
(b) and (e)
You cannot specify accessibility of local variables. They are accessible only within the block in which they are declared.
Objects themselves do not have any accessibility, only references to objects do. If no accessibility modifier (public, protected, or private) is given in the member declaration of a class, the member is only accessible to classes in the same package. A class does not have access to members with default accessibility declared in a superclass, unless both classes are in the same package. Inheritance has no consequence with respect to accessing members with default accessibility in the same package. Local variables cannot be declared static or given an accessibility modifier.
4.21
(c)
The line void k() { i++; } can be re-inserted without introducing errors. Re-inserting line (1) will cause the compilation to fail, since MyOtherClass will try to override a final method. Re-inserting line (2) will fail, since MyOtherClass will no longer have a default constructor. The main() method needs to call the default constructor. Re-inserting line (3) will work without any problems, but re-inserting line (4) will fail, since the method will try to access a private member of the superclass.
4.22
(f)
An object reference is needed to access non-static members. Static methods do not have the implicit object reference this, and must always supply an explicit object reference when referring to non-static members. The static method main() refers legally to the non-static method func() using the reference variable ref. Static members are accessible both from static and non-static methods, using their simple names.
4.23
(c)
Local variables can have the same name as member variables. The local variables will simply shadow the member variables with the same names. Declaration (4) defines a static method that tries to access a variable named a, which is not locally declared. Since the method is static, this access will only be valid if variable a is declared static within the class. Therefore, declarations (1) and (4) cannot occur in the same class definition, while declarations (2) and (4) can.
4.24
(b)
The keyword this can only be used in non-static code, like in non-static methods. Only one occurrence of each static variable of a class is created. This occurrence is shared among all the objects of the class (or for that matter, by other clients). Local variables are only accessible within the local scope, regardless of whether the local scope is defined within a static context.
4.25
(c)
The variable k cannot be declared synchronized. Only methods and code blocks can be synchronized.
4.26
(c)
The declaration abstract int t; is not legal. Keywords static and final are valid modifiers for both field and method declarations. The modifiers abstract and native are only valid for methods.
4.27
(a) and (c)
Abstract classes can contain both final methods and non-abstract methods. Non-abstract classes cannot, however, contain abstract methods. Nor can abstract classes be final. Only methods can be declared native.
4.28
(a)
The transient keyword signifies that the fields should not be stored when objects are serialized. Constructors cannot be declared abstract. When an array object is created, as in (c), the elements in the array object are assigned the default value corresponding to the type of the elements. Whether the reference variable denoting the array object is a local or a member variable is irrelevant. Abstract methods from a superclass need not be implemented by a subclass. The subclass must then be declared abstract.

Control Flow, Exception Handling, and Assertions
5.1
(d)
The program will display the letter b when run. The second if statement is evaluated since the boolean expression of the first if statement is true. The else clause belongs to the second if statement. Since the boolean expression of the second if statement is false, the if block is skipped and the else clause is executed.
5.2
(a), (b), and (e)
The conditional expression of an if statement can have any subexpressions, including method calls, as long as the whole expression evaluates to a value of type boolean. The expression (a = b) does not compare the variables a and b, but assigns the value of b to the variable a. The result of the expression is the value being assigned. Since a and b are boolean variables, the value returned by the expression is also boolean. This allows the expression to be used as the condition for an if statement. An if statement must always have an if block, but the else clause is optional. The expression if (false) ; else ; is legal. In this case, both the if block and the else block are simply the empty statement.
5.3
(f)
There is nothing wrong with the code. The case and default labels do not have to be specified in any specific order. The use of the break statement is not mandatory, and without it the control flow will simply fall through the labels of the switch statement.
5.4
(a)
The type of the switch expression must be either byte, char, short, or int. This excludes (b) and (e). The type of the case labels must be assignable to the type of the switch expression. This excludes (c) and (d).
5.5
(e)
The loop body is executed twice and the program will print 3. The first time the loop is executed, the variable i changes from 1 to 2 and the variable b changes from false to true. Then the loop condition is evaluated. Since b is true, the loop body is executed again. This time the variable i changes from 2 to 3 and the variable b changes from true to false. The loop condition is now evaluated again. Since b is now false, the loop terminates and the current value of i is printed.
5.6
(b) and (e)
Both the first and the second number printed will be 10. Both the loop body and the increment expression will be executed exactly 10 times. Each execution of the loop body will be directly followed by an execution of the increment expression. Afterwards, the condition j<10 is evaluated to see whether the loop body should be executed again.
5.7
(c)
Only (c) contains a valid for loop. The initializer in a for statement can contain either declarations or a list of expression statements, but not both as attempted in (a). The loop condition must be of type boolean. (b) tries to use an assignment of an int value (notice the use of = rather than ==) as a loop condition and is, therefore, not valid. The loop condition in the for loop (d) tries to use the uninitialized variable i, and the for loop in (e) is simply syntactically invalid.
5.8
(f)
The code will compile without error, but will never terminate when run. All the sections in the for header are optional and can be omitted (but not the semicolons).
An omitted loop condition is interpreted as being true. Thus, a for loop with an omitted loop condition will never terminate, unless a break statement is encountered in the loop body. The program will enter an infinite loop at (4).
5.9
(b), (d), and (e)
The loop condition in a while statement is not optional. It is not possible to break out of the if statement in (c). Notice that if the if statement had been placed within a labeled block, a switch statement, or a loop, the usage of break would be valid.
5.10
(a) and (d)
"i=1, j=0" and "i=2, j=1" are part of the output. The variable i iterates through the values 0, 1, and 2 in the outer loop, while j toggles between the values 0 and 1 in the inner loop. If the values of i and j are equal, the printing of the values is skipped and the execution continues with the next iteration of the outer loop. The following can be deduced when the program is run: variables i and j are both 0 and the execution continues with the next iteration of the outer loop. "i=1, j=0" is printed and the next iteration of the inner loop starts. Variables i and j are both 1 and the execution continues with the next iteration of the outer loop. "i=2, j=0" is printed and the next iteration of the inner loop starts. "i=2, j=1" is printed, j is incremented, j < 2 fails, and the inner loop ends. Variable i is incremented, i < 3 fails, and the outer loop ends.
5.11
(b)
The code will fail to compile, since the conditional expression of the if statement is not of type boolean. The conditional expression of an if statement must be of type boolean. The variable i is of type int. There is no conversion between boolean and other primitive types.
5.12
(d)
Implementation (4) will correctly return the largest value. The if statement does not return any value and, therefore, cannot be used as in implementations (1) and (2). Implementation (3) is invalid since neither the switch expression nor the case label values can be of type boolean.
5.13
(c)
As it stands, the program will compile correctly and will print "3, 2" when run. If the break statement is replaced with a continue statement, the loop will perform all four iterations and will print "4, 3". If the break statement is replaced with a return statement, the whole method will end when i equals 2, before anything is printed. If the break statement is simply removed, leaving the empty statement (;), the loop will complete all four iterations and will print "4, 4".
5.14
(a) and (c)
The block construct {} is a compound statement. The compound statement can contain zero or more arbitrary statements. Thus, {{}} is a legal compound statement, containing one statement that is also a compound statement, containing no statement. The block { continue; } by itself is not valid, since the continue statement cannot be used outside the context of a loop. (c) is a valid example of breaking out of a labeled block. (d) is not valid for the same reasons (b) was not valid. The statement at (e) is not true, since the break statement can also be used to break out of labeled blocks, as illustrated by (c).
5.15
(d)
The program will only print 1, 4, and 5, in that order. The expression 5/k will throw an ArithmeticExecption, since k equals 0. Control is transferred to the first catch block, since it is the first block that can handle arithmetic exceptions. This exception handler simply prints 1. The exception has now been caught and normal execution can resume. Before leaving the try statement, the finally block is executed. This block prints 4. The last statement of the main() method prints 5.
5.16
(b) and (e)
If run with one argument, the program will print the given argument followed by "The end". The finally block will always be executed, no matter how control leaves the try block.
5.17
(d)
The program will compile without error, but will throw a NullPointerException when run. The throw statement can only throw Throwable objects. A NullPointerException will be thrown if the expression of the throw statement results in a null reference.
5.18
(c) and (d)
Normal execution will only resume if the exception is caught by the method. The uncaught exception will propagate up the runtime stack until some method handles it. An overriding method need only declare that it can throw a subset of the checked exceptions the overridden method can throw. The main() method can declare that it throws checked exceptions just like any other method. The finally block will always be executed, no matter how control leaves the try block.
5.19
(b)
The program will print 1 and 4, in that order. An InterruptedException is handled in the first catch block. Inside this block a new RuntimeException is thrown. This exception was not thrown inside the try block and will not be handled by the catch blocks, but will be sent to the caller of the main() method. Before this happens, the finally block is executed. The code printing 5 is never reached, since the runtimeException remains uncaught after the execution of the finally block.
5.20
(a)
The program will print 2 and throw an InterruptedException. An InterruptedException is thrown in the try block. There is no catch block to handle the exception, so it will be sent to the caller of the main() method, that is, to the default exception handler. Before this happens, the finally block is executed. The code printing 3 is never reached.
5.21
(b)
The only thing that is wrong with the code is the ordering of the catch and finally blocks. If present, the finally block must always appear last in a try-catch-finally construct.
5.22
(a)
Overriding methods can specify all, none, or a subset of the checked exceptions the overridden method declares in its throws clause. The InterruptedException is the only checked exception specified in the throws clause of the overridden method. The overriding method f() need not specify any checked exception from the throws clause of the overridden method.
5.23
(c)
The overriding f() method in MyClass is not permitted to throw the checked InterruptedException, since the f() method in class A does not throw this exception. To avoid compilation errors, either the overriding f() method must not throw an InterruptedException or the overridden f() method must declare that it can throw an InterruptedException.
5.24
(c) and (d)
Statements (c) and (d) will throw an AssertionError because the first expression is false. Statement (c) will report true as the error message, while (d) will report false as the error message.
5.25
(b) and (d)
-ea (enable assertions) is a valid runtime option, not -ae. -source 1.4 is a compile time option. -dsa (disable system assertions) is a valid runtime option, not -dea.
5.26
(e)
The class of exceptions thrown by assertion statements is always AssertionError.
5.27
(c)
Assertions can be enabled or disabled at runtime, but the assert statements are always compiled into bytecode.
5.28
(a) and (b)
Statement (a) will cause the assert statement to throw an AssertionError since (-50 > -50) evaluates to false. Statement (b) will cause the expression 100/value to throw an ArithmeticException since an integer division by zero is attempted.
5.29
(a) and (d)
Option (a) enables assertions for all non-system classes, while (d) enables assertions for all classes in the package org and its subpackages. Options (b), (c), and (f) try to enable assertions in specifically named classes: Bottle, org.example, and org.example.ttp. Option (e) is not a valid runtime option.
5.30
(c)
The assert statement correctly asserts that 150 is greater than 100 and less than 200.
5.31
(b) and (d)
The AssertionError class, like all other error classes, is not a checked exception, and need not be declared in a throws clause. After an AssertionError is thrown, it is propagated exactly the same way as other exceptions, and can be caught by a try-catch construct.
5.32
(d)
The class Error is the direct superclass of AssertionError.
5.33
(c) and (d)
The command line enables assertions for all non-system classes, except for those in the com package or one of its subpackages. Assertions are not enabled for the system classes in (b) and (e).

Object-oriented Programming
6.1
(a) and (b)
The extends clause is used to specify that a class extends another class. A subclass can be declared abstract regardless of whether the superclass was declared abstract. Private, overridden, and hidden members from the superclass are not inherited by the subclass. A class cannot be declared both abstract and final, since an abstract class needs to be extended to be useful and a final class cannot be extended. The accessibility of the class is not limited by the accessibility of its members. A class with all the members declared private can still be declared public.
6.2
(b) and (e)
Inheritance defines an is-a relation. Aggregation defines a has-a relation. The Object class has a public method named equals, but it does not have any method named length. Since all classes are subclasses of the Object class, they all inherit the equals() method. Thus, all Java objects have a public method named equals. In Java, a class can only extend a single superclass, but there is no limit on how many classes can extend a superclass.
6.3
(b) and (c)
A subclass need not redefine all the methods defined in the superclass. It is possible for a subclass to define a method with the same name and parameters as a method defined by the superclass, but then the return type should also be the same. This is called method overriding. A subclass can define a field that can hide a field defined in a superclass. Two classes cannot be the superclass of each other.
6.4
(a), (b), and (d)
Bar is a legal subclass of Foo that overrides the method g(). The statement a.j = 5 is not legal, since the member j in class Bar cannot be accessed through a Foo reference. The statement b.i = 3 is not legal either, since the private member i cannot be accessed from outside of the class Foo.
6.5
(a)
A method can be overridden by defining a method with the same signature (i.e., name and parameter list) and return type as the method in a superclass. Only instance methods that are accessible by their simple name can be overridden. A private method, therefore, cannot be overridden in subclasses, but the subclasses are allowed to define a new method with exactly the same signature. A final method cannot be overridden. An overriding method cannot exhibit behavior that contradicts the declaration of the original method. An overriding method, therefore, cannot return a different type of value or declare that it throws more exceptions than the original method in the superclass.
6.6
(g)
It is not possible to invoke the doIt() method in A from an instance method in class C. The method in C needs to call a method in a superclass two levels up in the inheritance hierarchy. The super.super.doIt() strategy will not work, since super is a keyword and cannot be used as an ordinary reference, nor accessed like a field. If the member to be accessed had been a field, the solution would be to cast the this reference to the class of the field and use the resulting reference to access the field. Field access is determined by the declared type of the reference, whereas the instance method to execute is determined by the actual type of the object denoted by the reference.
6.7
(e)
The code will compile without errors. None of the calls to a max() method are ambiguous. When the program is run, the main() method will call the max() method in C with the parameters 13 and 29. This method will call the max() method in B with the parameters 23 and 39. The max() method in B will in turn call the max() method in A with the parameters 39 and 23. The max() method in A will return 39 to the max() method in B. The max() method in B will return 29 to the max() method in C. The max() method in C will return 29 to the main() method.
6.8
(c)
The simplest way to print the message in the class Message would be to use System. out.println(msg.text). The main() method creates an instance of MyClass, which results in the creation of a Message instance. The field msg denotes this Message object in MySuperclass and is inherited by the MyClass object. Thus, the message in the Message object can be accessed directly by msg.text in the print() method of MyClass.
6.9
(e)
The class MySuper does not have a default constructor. This means that constructors in subclasses must explicitly call the superclass constructor to provide the required parameters. The supplied constructor accomplishes this by calling super(num) in its first statement. Additional constructors can accomplish this either by calling the superclass constructor directly using the super() call, or by calling another constructor in the same class using the this() call, which in turn calls the superclass constructor. (a) and (b) are not valid since they do not call the superclass constructor explicitly. (d) fails since the super() call must always be the first statement in the constructor body. (f) fails since the super() and this() calls cannot be combined.
6.10
(b)
In a subclass without any declared constructors, the implicit default constructor will call super(). The use of the super() and this() statements are not mandatory as long as the superclass has a default constructor. If neither super() nor this() is declared as the first statement in the body of a constructor, then super() will implicitly be the first statement. A constructor body cannot have both a super() and a this() statement. Calling super() will not always work, since a superclass might not have a default constructor.
6.11
(d)
The program will print 12 followed by Test. When the main() method is executed, it will create a new instance of B by giving "Test" as argument. This results in a call to the constructor of class B that has one String parameter. The constructor does not explicitly call any superclass constructor, but instead the default constructor of the superclass A is called implicitly. The default constructor of class A calls the constructor in A that has two String parameters, giving it the arguments "1", "2". This constructor calls the constructor with one String parameter, passing the argument "12". This constructor prints the argument. Now the execution of all the constructors in A is completed, and execution continues in the constructor of B. This constructor now prints the original argument "Test" and returns to the main() method.
6.12
(b) and (c)
Interfaces do not have any implementations and only permit multiple interface inheritance. An interface can extend any number of other interfaces and can be extended by any number of interfaces. Fields in interfaces are always static and method prototypes in interfaces are never static.
6.13
(a), (c), and (d)
Fields in interfaces declare named constants, and are always public, static, and final. None of these modifiers are mandatory in a constant declaration. All named constants must be explicitly initialized in the declaration.
6.14
(a) and (d)
The keyword implements is used when a class inherits from an interface. The keyword extends is used when an interface inherits from another interface or a class inherits from another class.
6.15
(e)
The code will compile without errors. The class MyClass declares that it implements the interfaces Interface1 and Interface2. Since the class is declared abstract, it does not need to supply implementations for all the method prototypes defined in these interfaces. Any non-abstract subclasses of MyClass must provide the missing method implementations. The two interfaces share a common method prototype void g(). MyClass provides an implementation for this prototype that satisfies both Interface1 and Interface2. Both interfaces provide declarations of constants named VAL_B. This can lead to an ambiguity when referring to VAL_B by its simple name from MyClass. The ambiguity can be resloved by using fully qualified names: Interface1.VAL_B and Interface2.VAL_B. However, there are no problems with the code as it stands.
6.16
(a) and (c)
Declaration (b) fails since it contains an illegal forward reference to its own named constant. The field type is missing in declaration (d). Declaration (e) tries illegally to use the protected modifier, even though named constants always have public accessibility.
6.17
(c)
The program will throw a java.lang.ClassCastException in the assignment at (3) when run. The statement at (1) will compile since the assignment is done from a subclass reference to a superclass reference. The cast at (2) assures the compiler that arrA will refer to an object that can be referenced by arrB. This will work when run since arrA will refer to an object of type B[]. The cast at (3) will also assure the compiler that arrA will refer to an object that can be referenced by arrB. This will not work when run since arrA will refer to an object of type A[].
6.18
(d)
Line (4) will cause a compile-time error since it attempts to assign a reference value of a supertype object to a reference of a subtype. The type of the source reference value is MyClass and the type of the destination reference is MySubclass. Lines (1) and (2) will compile since the reference is assigned a reference value of the same type. Line (3) will also compile since the reference is assigned a reference value of a subtype.
6.19
(e)
Only the assignment I1 b = obj3 is valid. The assignment is allowed since C3 extends C1, which implements I1. Assignment obj2 = obj1 is not legal since C1 is not a subclass of C2. Assignments obj3 = obj1 and obj3 = obj2 are not legal since neither C1 nor C2 is a subclass of C3. Assignment I1 a = obj2 is not legal since C2 does not implement I1. Assignment I2 c = obj1 is not legal since C1 does not implement I2.
6.20
(b)
The statement would be legal at compile time, since the reference x might actually refer to an object of the type Sub. The cast tells the compiler to go ahead and allow the assignment. At runtime, the reference x may turn out to denote an object of the type Super instead. If this happens, the assignment will be aborted and a ClassCastException will be thrown.
6.21
(c)
Only A a = d is legal. The reference value in d can be assigned to a since D implements A. The statements c = d and d = c are illegal since there is no subtype-supertype relationship between classes C and D. Even though a cast is provided, the statement d = (D) c is illegal. The object referred to by c cannot possibly be of type D, since D is not a subclass of C. The statement c = b is illegal since assigning a reference value of a reference of type B to a reference of type C requires a cast.
6.22
(a), (b), and (c)
The program will print A, B, and C when run. The object denoted by reference a is of type C. The object is also an instance of A and B, since C is a subclass of B and B is a subclass of A. The object is not an instance of D.
6.23
(b)
The expression (o instanceof B) will return true if the object referred to by o is of type B or a subtype of B. The expression (!(o instanceof C)) will return true unless the object referred to by o is of type C or a subtype of C. Thus, the expression (o instanceof B) && (!(o instanceof C)) will only return true if the object is of type B or a subtype of B that is not C or a subtype of C. Given objects of classes A, B, and C, this expression will only return true for objects of class B.
6.24
(a)
The program will print all of I, J, C, and D when run. The object referred to by reference x is of class D. Class D extends class C and class C implements interface I. This makes I, J, and C supertypes of class D. A reference of type D can be cast to any of its supertypes and is, therefore, an instanceof these types.
6.25
(e)
The program will print 2 when System.out.println(ref2.f()) is executed. The object referenced by ref2 is of class C, but the reference is of type B. Since B contains a method f(), the method call will be allowed at compile time. During execution it is determined that the object is of class C, and dynamic method lookup will cause the overridden method in C to be executed.
6.26
(c)
The program will print 1 when run. The f() methods in A and B are private and are not accessible by the subclasses. Because of this, the subclasses cannot overload or override these methods, but simply define new methods with the same signature. The object being called is of class C. The reference used to access the object is of type B. Since B contains a method g(), the method call will be allowed at compile time. During execution it is determined that the object is of class C, and dynamic method lookup will cause the overridden method g() in B to be called. This method calls a method named f(). It can be determined during compilation that this can only refer to the f() method in B, since the method is private and cannot be overridden. This method returns the value 1, which is printed.
6.27
(c) and (d)
The code as it stands will compile without error. The use of inheritance in this code is not justifiable since, conceptually, a planet is-not-a star. The code will fail if the name of the field starName is changed in the Star class since the subclass Planet tries to access it using the name starName. An instance of Planet is not an instance of HeavenlyBody. Neither Planet nor Star implements HeavenlyBody.
6.28
(b)
The code will compile without error. The use of aggregation in this code is justifiable. The code will not fail to compile if the name of the field starName is changed in the Star class, since the Planet class does not try to access the field by name, but instead uses the public method describe() in the Star class to do that. An instance of Planet is not an instance of HeavenlyBody since it neither implements HeavenlyBody nor extends a class that implements HeavenlyBody.

Nested Classes And Interfaces
7.1
(e)
The code will compile without error and will print 123 when run. An instance of the Outer outer will be created and the field secret will be initialized to 123. A call to the createInner() method will return a reference to a newly created Inner instance. This object is an instance of a non-static member class and is associated with the outer instance. This means that an object of a non-static member class has access to the members within the outer instance. Since the Inner class is nested in the class containing the field secret, this field is accessible to the Inner instance, even though the field secret is declared private.
7.2
(b) and (e)
A static member class is in many respects like a top-level class, and can contain non-static fields. Instances of non-static member classes are created in the context of an outer instance. The outer instance is inherently associated with the inner instance. Several inner class instances can be created and associated with the same outer instance. Static classes do not have any inherent outer instance. A static member interface, just like top-level interfaces, cannot contain non-static fields. Nested interfaces are always static.
7.3
(e)
The code will fail to compile, since the expression ((State) this).val in the method restore() of the class Memento is invalid. The correct way to access the field val in the class State, which is hidden by the field val in the class Memento, is to use the expression State.this.val. Other than that, there are no problems with the code.
7.4
(d)
The program will compile without error, and will print 1, 3, 4, in that order, when run. The expression B.this.val will access the value 1 stored in the field val of the (outer) B instance associated with the (inner) C object denoted by the reference obj. The expression C.this.val will access the value 3 stored in the field val of the C object denoted by the reference obj. The expression super.val will access the field val from A, the superclass of C.
7.5
(c) and (d)
The class Inner is a non-static member class of the Outer class, and its full name is Outer.Inner. The Inner class does not inherit from the Outer class. The method named doIt is, therefore, neither overridden nor overloaded. Within the scope of the Inner class, the doIt() method of the Outer class is hidden by the doIt() method of the Inner class.
7.6
(e)
Non-static member classes, unlike top-level classes, can have any accessibility modifier. Static member classes can only be declared in top-level or nested static member classes and interfaces. Only static member classes can be declared static. Declaring a class static only means that instances of the class are created without having an outer instance. This has no bearing on whether the members of the class can be static or not.
7.7
(d) and (e)
The methods labeled (1) and (3) will not compile, since the non-final parameter i is not accessible from within the inner class. The syntax of the anonymous class in the method labeled (2) is not correct, as the parameter list is missing.
7.8
(a) and (d)
No other static members, except final static fields, can be declared within a non-static member class. Members in outer instances are directly accessible using simple names (provided they are not hidden). Fields in nested static member classes need not be final. Anonymous classes cannot have constructors, since they have no names. Nested classes define distinct types from the enclosing class, and the instanceof operator does not take the type of the outer instance into consideration.
7.9
(b)
Classes can be declared as members of top-level classes. Such a class is a static member class if it is declared static, otherwise, it is a non-static member class. Top-level classes, local classes, and anonymous classes cannot be declared static.

Object Lifetime
8.1
(e)
An object is only eligible for garbage collection if all remaining references to the object are from other objects that are also eligible for garbage collection. Therefore, if an object obj2 is eligible for garbage collection and object obj1 contains a reference to it, then object obj1 must also be eligible for garbage collection. Java does not have a keyword delete. An object will not necessarily be garbage collected immediately after it becomes unreachable. However, the object will be eligible for garbage collection. Circular references do not prevent objects from being garbage collected, only reachable references do. An object is not eligible for garbage collection as long as the object can be accessed by any live thread. An object that has been eligible for garbage collection can be made non-eligible. This occurs if the finalize() method of the object creates a reachable reference to the object.
8.2
(b)
Before (1), the String object initially referenced by arg1 is denoted by both msg and arg1. After (1), the String object is only denoted by msg. At (2), reference msg is assigned a new reference value. This reference value denotes a new String object created by concatenating several other String objects. After (2), there are no references to the String object initially referenced by arg1. The String object is now eligible for garbage collection.
8.3
(b)
The Object class defines a protected finalize() method. All classes inherit from Object, thus, all objects have a finalize() method. Classes can override the finalize() method and, as with all overriding, the new method must not reduce the accessibility. The finalize() method of an eligible object is called by the garbage collector to allow the object to do any cleaning up, before the object is destroyed. When the garbage collector calls the finalize() method, it will ignore any exceptions thrown by the finalize() method. In all other cases, normal exception handling occurs when an exception is thrown during the execution of the finalize() method, that is, exceptions are not simply ignored. Calling the finalize() method does not in itself destroy the object. Chaining of the finalize() methods is not enforced by the compiler, and it is not mandatory to call the overridden finalize() method.
8.4
(d)
The finalize() method is like any other method, it can be called explicitly if it is accessible. However, the intended purpose of the method is to be called by the garbage collector in order to clean up before an object is destroyed. Overloading the finalize() method name is allowed, but only the method with the original signature will be called by the garbage collector. The finalize() method in Object is protected. This means that overriding methods must be declared either protected or public. The finalize() method in Object can throw any Throwable object. Overriding methods can limit the range of throwables to unchecked exceptions. Further overridden definitions of this method in subclasses will not be able to throw checked exceptions.
8.5
(b)
The finalize() method will never be called more than once on an object, even if the finalize() method resurrects the object. An object can be eligible for garbage collection even if there are references denoting the object, as long as the objects owning these references are also eligible for garbage collection. There is no guarantee that the garbage collector will destroy an eligible object before the program terminates. The order in which the objects are destroyed is not guaranteed. The finalize() method can make an object that has been eligible for garbage collection, accessible again by a live thread.
8.6
(c), (e), and (f)
Static initializer blocks (a) and (b) are not legal since the fields alive and STEP are non-static and final, respectively. (d) is syntactically not a legal static initializer block.
8.7
(c)
The program will compile without error and will print 50, 70, 0, 20, 0 when run. All fields are given default values unless they are explicitly initialized. Field i is assigned the value 50 in the static initializer block that is executed when the class is initialized. This assignment will override the explicit initialization of field i in its declaration statement. When the main() method is executed, the static field i is 50 and the static field l is 0. When an instance of the class is created using the new operator, the value of static field l (i.e., 0) is passed to the constructor. Before the body of the constructor is executed, the instance initializer block is executed, which assigns values 70 and 20 to fields j and l, respectively. When the body of the constructor is executed, the fields i, j, k, and l, and the parameter m, have the values 50, 70, 0, 20, and 0, respectively.
8.8
(f)
This class has a blank final boolean variable active. This variable must be initialized when an instance is constructed or else the code will not compile. The keyword static is used to signify that a block is a static initializer block. No keyword is used to signify that a block is an instance initializer block. (a) and (b) are not instance initializers blocks, and (c), (d), and (e) fail to initialize the blank final variable active.
8.9
(c)
The program will compile without error and will print 2, 3, and 1 when run. When the object is created and initialized, the instance initializer block is executed first, printing 2. Then the instance initializer expression is executed, printing 3. Finally, the constructor body is executed, printing 1. The forward reference in the instance initializer block is legal, as the use of the field m is on the left-hand side of the assignment.
8.10
(e)
The program will compile without error and will print 1, 3, and 2 when run. First, the static initializers are executed when the class is initialized, printing 1 and 3. When the object is created and initialized, the instance initializer block is executed, printing 2.
8.11
(c) and (e)
Line A will cause illegal redefinition of the field width. Line B uses an illegal forward reference to the fields width and height. The assignment in line C is legal. Line D is not a legal initializer since it is neither a declaration nor a block. Line E declares a local variable inside an initializer block.

Threads
9.1
(c)
Create a new Thread object and call the method start(). The call to the start() method will return immediately, and the thread will start executing the run() method asynchronously.
9.2
(c)
When extending the Thread class, the run() method should be overridden to provide the code executed by the thread. This is analogous to implementing the run() method of the Runnable interface.
9.3
(b) and (e)
The Thread class implements the Runnable interface and is not abstract. A program terminates when the last non-daemon thread ends. The Runnable interface has a method named run, but the interface does not dictate that implementations must define a method named start. Calling the run() method on a Runnable object does not necessarily create a new thread. Method run() is the method executed by a thread. Instances of the Thread class must be created to spawn new threads.
9.4
(e)
The program will compile without errors, and will simply terminate without any output when run. Two thread objects will be created, but they will never be started. The start() method must be called on the thread objects to make the threads execute the run() method asynchronously.
9.5
(a) and (e)
Because the exact behavior of the scheduler is undefined, the text A, B, and End can be printed in any order. The thread printing B is a daemon thread, which means that the program may terminate before the thread manages to print the letter.
9.6
(a)
No two threads can concurrently execute synchronized methods on the same object. This does not prevent one thread from executing a non-synchronized method while another thread executes a synchronized method on the same object. The synchronization mechanism in Java acts like recursive semaphores, which means that during the time a thread owns the lock, it may enter and re-enter any region of code associated with the lock.
9.7
(b)
One cannot be certain whether any of the letters i, j, and k will be printed during execution. For each invocation of the doit() method, each variable pair is incremented and their values are always equal when the method returns. The only way a letter could be printed would be if the method check() was executed between the time the first and the second variable were incremented. Since the check() method does not depend on owning any lock, it can be executed at any time, and the method doit() cannot protect the atomic nature of its operations by acquiring locks.
9.8
(d)
A thread dies when the execution of the run() method ends. The call to the start() method is asynchronous, that is, it returns immediately, and it enables the thread for running. Calling the sleep() or wait() methods will only block the thread temporarily.
9.9
(b) and (d)
The inner createThread() call is evaluated first, and will print 23 as the first number. The last number the main thread prints is 14. After the main thread ends, the thread created by the inner createdThread() completes its join() call and prints 22. After this thread ends, the thread created by the outer createThread() call completes its join() call and prints the number 12 before the program terminates.
9.10
(e)
The exact behavior of the scheduler is not defined. There is no guarantee that a call to the yield() method will grant other threads use of the CPU.
9.11
(b)
The notify() method is defined in the Object class.
9.12
(a)
The priority of a thread is set by calling the setPriority() method in the Thread class. No Thread constructor accepts a priority level as an argument.
9.13
(a) and (c)
A thread can hold multiple locks; for example, by nesting synchronized blocks. Invoking the wait() method on an object whose lock is held by the current thread will relinquish the lock for the duration of the call. The notify() method does not relinquish any locks.
9.14
(c)
An IllegalMonitorStateException will be thrown if the wait() method is called when the current thread does not hold the lock of the object.
9.15
(a), (c), (d), and (e)
The thread terminates once the run() method completes execution.

Fundamental Classes
10.1
(b)
The method hashCode() in the Object class returns a hash code value of type int.
10.2
(e)
All arrays are genuine objects and inherit all the methods defined in the Object class, including the clone() method. Neither the hashCode() method nor the equals() method is declared final in the Object() class, and it cannot be guaranteed that implementations of these methods will differentiate between all objects.
10.3
(a)
The clone() method of the Object class will throw a CloneNotSupportedException if the class of the object does not implement the Cloneable interface.
10.4
(a), (c), and (d)
The class java.lang.Void is considered a wrapper class, although it does not wrap any value. There is no class named java.lang.Int, but there is a wrapper class named java.lang.Integer. A class named java.lang.String also exists, but it is not a wrapper class since all strings in Java are objects.
10.5
(c) and (d)
The classes Character and Boolean are non-numeric wrapper classes and they do not extend the Number class. The classes Byte, Short, Integer, Long, Float, and Double are numeric wrapper classes that extend the Number class.
10.6
(a), (b), and (d)
All instances of wrapper classes are immutable.
10.7
(b) and (c)
All instances of wrapper classes except Void and Character have a constructor that accepts a string parameter. The class Object has only a default constructor.
10.8
(e)
While all numeric wrapper classes have the methods byteValue(), doubleValue(), floatValue(), intValue(), longValue(), and shortValue(), only the Boolean class has the booleanValue() method. Likewise, only the Character class has the charValue() method.
10.9
(b) and (d)
String is not a wrapper class. All wrapper classes except Boolean and Void have a compareTo() method. Only the numeric wrapper classes have an intValue() method. The Byte class, like all other numeric wrapper classes, extends the Number class.
10.10
(b) and (d)
The lines labeled (2) and (4) will print 11 exactly, since their expressions will return the int value 11. The expression Math.ceil(v) will return the double value 11.0, which will be printed as 11.0. The expression Math.floor(v) will return 10.0d.
10.11
(a)
The Math class does not have a method named tan2. However, it does have a method named atan2, which converts rectangular coordinates to polar coordinates.
10.12
(a)
The method round(float) will return a value of type int. A round(double) method also exists, which returns a value of type long.
10.13
(c)
The rounding function ceil() will return a value of type double. This is in contrast to the round() methods that will return values of integer types.
10.14
(b)
The value -0.5 is rounded up to 0 and the value 0.5 is rounded up to 1.
10.15
(b), (c), and (d)
The expression will evaluate to one of the numbers 0, 1, 2, or 3. Each number has an equal probability of being returned by the expression.
10.16
(b) and (e)
The operators - and & cannot be used in conjunction with a String object. The operators + and += perform concatenation on strings, and the dot operator accesses members of the String object.
10.17
(d)
The expression str.substring(2, 5) will extract the substring "kap". The method extracts the characters from index 2 to index 4, inclusive.
10.18
(d)
The program will print str3str1 when run. The concat() method will create and return a new String object, which is the concatenation of the current String object and the String object given as an argument. The expression statement str1.concat(str2) creates a new String object, but its reference value is not stored.
10.19
(c)
The trim() method of the String class returns a string where both the leading and the trailing white space of the original string have been removed.
10.20
(a) and (c)
The String class and all wrapper classes are declared final and, therefore, cannot be extended. The clone() method is declared protected in the Object class. String objects are immutable and, therefore, cannot be modified. The classes String and StringBuffer are unrelated.
10.21
(a), (b), (c), and (e)
The expressions ('c' + 'o' + 'o' + 'l') and ('o' + 'l') are of type int due to numeric promotion. Expression (d) is illegal since the String class has no constructor taking a single int parameter. Expression (a) is legal since string literals denote String objects and can be used just like any other object.
10.22
(d)
The constant expressions "ab" + "12" and "ab" + 12 will, at compile time, be evalutated to the string-valued constant "ab12". Both variables s and t are assigned a reference to the same interned String object containing "ab12". The variable u is assigned a new String object, created using the new operator.
10.23
(a), (c), and (d)
The String class does not have a constructor that takes a single int as a parameter.
10.24
(e)
The String class has no reverse() method.
10.25
(d)
The expression "abcdef".charAt(3) evaluates to the character 'd'. The charAt() method takes an int value as an argument and returns a char value. The expression ("abcdef").charAt(3) is legal. It also evaluates to the character 'd'. The index of the first character in a string is 0.
10.26
(e)
The expression "Hello there".toLowerCase().equals("hello there") will evaluate to true. The equals() method in the String class will only return true if the two strings have the same sequence of characters.
10.27
(c)
The variable middle is assigned the value 6. The variable nt is assigned the string "nt". The substring "nt" occurs three times in the string "Contentment!", starting at indexes 2, 5, and 9. The call s.lastIndexOf(nt, middle) returns the start index of the last occurrence of "nt", searching backwards from position 6.
10.28
(b)
The code will fail to compile since the expression (s == sb) is illegal. It compares references of two classes that are not related.
10.29
(e)
The program will compile without errors and will print have a when run. The contents of the string buffer are truncated down to 6 characters.
10.30
(a), (b), and (d)
The StringBuffer class does not have a constructor that takes an array of char as a parameter.
10.31
(a)
The StringBuffer class does not define a trim() method.
10.32
(d)
The program will construct an immutable String object containing "eenny" and a StringBuffer object containing " miny". The concat() method returns a reference value to a new immutable String object containing "eenny meeny", but the reference value is not stored. The append() method appends the string " mo" to the string buffer.

Collections and Maps
11.1
(a), (d), and (e)
Set, Collection and Map are core interfaces in the collections framework. LinkedList is a class that implements the List interface. There is no class or interface named Bag.
11.2
(b) and (e)
The java.util package provides map implementations named HashMap and TreeMap. It does not provide any implementations named HashList, ArraySet, and ArrayMap.
11.3
(d)
The List interface is implemented by collections that maintain sequences of possibly non-unique elements. Elements retain their ordering in the sequence. Collection classes implementing SortedSet only allow unique elements that are maintained in a sorted order.
11.4
(a) and (c)
Some operations on a collection may throw an UnsupportedOperationException. This exception type is unchecked, and the code is not required to explicitly handle unchecked exceptions. A List allows duplicate elements. An ArrayList implements a resizable array. The capacity of the array will be expanded automatically when needed. The List interface defines a get() method, but there is no method by that name in the Collection interface.
11.5
(d)
The program will compile without error, and will print all primes below 25 when run. All the collection implementations used in the program implement the Collection interface. The implementation instances are interchangeable when denoted by Collection references. None of the operations performed on the implementations will throw an UnsupportedOperationException. The program finds the primes below 25 by removing all values divisible by 2, 3, and 5 from the set of values from 2 through 25.
11.6
(a), (b), and (d)
The methods add(), retainAll(), and iterator() are defined in the Collection interface. The get() and indexOf() methods are defined in the List interface.
11.7
(b)
The remove() method removes the last element returned by either next() or previous(). The four next() calls return A, B, C, and D. D is subsequently removed. The two previous() calls return C and B. B is subsequently removed.
11.8
(b) and (d)
The methods add() and retainAll(), return the value true if the collection was modified during the operation. The contains() and containsAll() methods return a boolean value, but these membership operations never modify the current collection, and the return value indicates the result of the membership test. The clear() method does not have a return value.
11.9
(c) and (d)
The Map interface defines the methods remove() and values(). It does not define methods contains(), addAll(), and toArray(). Methods with these names are defined in the Collection interface, but Map does not inherit from Collection.
11.10
(b) and (d)
Although all the keys in a map must be unique, multiple identical values may exist. Since values are not unique, the values() method returns a Collection instance and not a Set instance. The collection objects returned by the keySet(), entrySet(), and values() methods are backed by the original Map object. This means that changes made in one are reflected in the other. Although implementations of SortedMap keep the entries sorted on the keys, this is not a requirement for classes that implement Map. For instance, the entries in a HashMap are not sorted.
11.11
(a)
[1, 3, 2] is printed. First, "1" and "2" are appended to an empty list. Next, "3" is inserted between "1" and "2", and then the list is duplicated. The original list is concatenated with the copy. The sequence of elements in the list is now "1", "3", "2", "1", "3", "2". Then a sublist view allowing access to elements from index 2 to index 5 (exclusive) is created (i.e., the subsequence "2", "1", "3"). The sublist is cleared, thus removing the elements. This is reflected in the original list and the sequence of elements is now "1", "3", "2".
11.12
(c) and (e)
The classes TreeSet and TreeMap implement the comparator() method. The comparator() method is defined in the SortedSet and SortedMap interfaces, and the TreeSet and TreeMap classes implement these interfaces.
11.13
(a) and (d)
The key of a Map.Entry cannot be changed since the key is used for locating the entry within the list. Although iterators obtained for the entry set of a map have a remove() method, the entries themselves do not. Map.Entry has a method named setValue, but its return type is Object.
11.14
(a) and (c)
(b) is eliminated since the hashCode() method cannot claim inequality if the equals() method claims equality. (d) and (e) are eliminated since the equal() method must be reflexive, and the hashCode() method must consistently return the same hash value during the execution.
11.15
(b), (d), and (e)
(a) and (c) fail to satisfy the properties of an equivalence relation. (a) is not transitive and (c) is not symmetric.
11.16
(c)
Of all the collection classes in the java.util package, only Vector and HashTable are thread-safe. The Collections class contains a static synchronizedCollectionType() method that creates thread-safe instances based on collections, which are not.
11.17
(a) and (e)
(b) is not correct since it will throw an ArithmeticException when called on a newly created Measurement object. (c) and (d) are not correct since they may return unequal hash values for two objects that are equal according to the equals() method.



rahulrastogi
rahulrastogi
Latest page update: made by rahulrastogi , Sep 14 2007, 1:39 AM EDT (about this update About This Update rahulrastogi Edited by rahulrastogi

13252 words added

view changes

- complete history)
Keyword tags: None
More Info: links to this page
There are no threads for this page.  Be the first to start a new thread.