Errata: A Programmer's Guide to Java™ Certification

A Comprehensive Primer

(First Edition)

Khalid A. Mughal and Rolf W. Rasmussen

ISBN 0201596148

This is an exhaustive list of corrections, etc. for the FIFTH and SIXTH PRINTING of the book.

Last updated October 6, 2002.

Acknowledgements:

Many thanks to the following readers for their diligent observations:
Michael F. Adolf, Tony Alicea, Kåre Auglænd, Jorge L. Barroso, Andre Beland, Darren Bruning, Paul Campbell, Roger Chang, Joanna Chappel, Laurian M Chirica, Arkadi Choufrine, Barry Colston, John Cotter, Frédéric Demers, Arthur De Souza, djc, William Ekiel, Darryl Failla, John Finlay, Christopher R. Gardner, Marco Garcia, Peter Gieser, George, Paul Graf, Shyamsundar Gururaj, Ray Ho, Leonardo Holanda, Zhu Hongjun, Kara Van Horn, Peter Horst, Nain Hwu, Kent Johnson, Samir Kanparia, Oleksiy Karpenko, Jeffrey Kenyon, Young Jin Kim, Kenneth Kisser, Billy Kutulas, Yi-Ming Lai, Robert M. Languedoc, Steve Lasley, Winser Lo, Naga Madipalli, Craig Main, Avinash Mandsaurwale, Thomas Mathai, S. Mehra, Yuan Meng, Simon Miller, William Moore, Anders Morch, George A. Murakami, Sandy Nemecek, Chun Pan, Abigail García Patiño, Anil Philip, Alfred Raouf, Peter Rorden, Christian Seifert, Gurpreet Singh, Christopher Stanwood, Swaminathan Subramanian, Siva Sundaram,  Manju Swamy, John Sweeney, Harmon Taylor, Andrew Tolopko, Ravi Verma, Per J. Walstrøm, Chun Wang, James Ward, Winky, Chun Wang, Jimmy Yang, Jennie Yip, Yanqu Zhou, Yingting Zhou.

Changes added October 6, 2002.

Page 22, Table 2.1 Keywords in Java

Add the keyword assert to the table.

Page 43, Casting

The following sentence is not correct:

"Casting the reference literal null, which is not of any type, to a reference type results in a compile time warning."

and should be replaced by:

"The reference literal null can be cast to any reference type."

Page 120, Review Question 4.17

Replace the choices with the following:

(a) Member variable i is accessible in  all classes in other packages. 
(b) Member variable j is accessible in all classes in other packages. 
(c) Member variable k is  accessible in all classes in other packages. 
(d) Member variable k is  accessible in subclasses only in other packages. 
(e) Member variable l is  accessible in all classes in other packages. 
(f) Member variable l is  accessible in subclasses only in other packages.

Page 123, final Members

In the middle of the page, replace the line beginning with:

" setKWH from the superclass ... "

with:

" setWatts() from the superclass ... "

Page 186, Review Question 6.5

Change choice (e) 

(e) The overriding method can have a different return value than the overridden method.

to (replace "value" with "type"):

(e) The overriding method can have a different return type than the overridden method.

Page 235, Example 7.6 Inheritance and Containment Hierarchy

With line (2) uncommented, the compiler distributed with J2SE 1.4 compiles the code without error. However, this is a recent change to the Sun compiler. We cannot see that the Java Language Specification (JLS) has been changed to allow such disambiguation, and other standards compliant compilers such as IBM's Jikes still reject the code. We don't know whether this is a case of misinterpreting the JLS, or a bug in the Sun Java compiler distributed with J2SE 1.4.

Page 284, Thread States

In the paragraph for Blocked state, make the following two changes:

Change "Blocking state" to "Blocked state".

Change the sentence:

"A thread also blocks if it fails ..."

to:

"A thread will be blocked if it fails ..."

Page 296, Section 10.1 Overview of the java.lang package

The bullet:

"The wrapper classes (Boolean, Character, Number, Byte, Short, Integer, Long, Float, Double)"

should read (delete Number):

"The wrapper classes (Boolean, Character, Byte, Short, Integer, Long, Float, Double)"

Page 320, Controlling String Buffer Capacity

In the middle of the page, change "\u0000" to '\u0000'

Page 333, Section 11.4 Lists

The sentence:

"The remove() method deletes and returns the element at the specified index, contracting the list accordingly."

should read:

"The remove(int index) method deletes and returns the element at the specified index, contracting the list accordingly."

Page 379, Example 12.12 Illustrating Menus

The following import statement can be deleted: 

import java.applet.*;

Page 469, Drawing Polygons

The sentence:

"The Polygon class has the following constructors:"

should read:

"The Polygon class has the following constructor:"

Page 569, Table 18.6 Writers

In the row for the PrintWriter, change the sentence:

"A filter that allows textual representations of ..."

to:

"A writer that allows textual representations of ..."

Page 583, Section 18.5 Random Access for Files

Change the exception in the constructors:

RandomAccessFile(String name, String mode) throws IOException
RandomAccessFile(File file, String mode) throws IOException

to:

RandomAccessFile(String name, String mode) throws FileNotFoundException
RandomAccessFile(File file, String mode) throws
FileNotFoundException

Changes added December 22, 2001.

Page 3, Declaring Members: Variables and Methods

In the middle of the page, replace the following:

"It also has a special method that has the same name as the class. Such methods are called constructors, ..."

with:

"It also has a special method-like declaration that has the same name as the class, (2). Such declarations are called constructors, ..."

Page 7, Section 1.5 Static Members

In the middle of the page, replace the sentence:

"Static members are distinguished from instance variables in a class definition by the keyword static in their declaration."

with:

"Static members are distinguished from instance members in a class definition by the keyword static in their declaration."

Page 24, Table 2.6 Examples of Octal and Hexadecimal Literals in Java

Replace the last row of the table:

-2147483648
-017777777777
-0x7fffffff

with:

-2147483648
-020000000000
-0x80000000

Page 40, Programming Exercise 2.1

A short note on creating and using packages.

A package statement can only occur as the first statement in a Java source file.
The statement

package com.acme;

instructs the compiler to place the Java byte code for all the classes (and interface) specified in the source file in the package com.acme.

Think of a package name as a path in the file system.
In this case the package name com.acme corresponds to the path name com/acme. So the Java byte code for all the classes (and interface) specified in the source file Exercise1.java will be placed under the catalog com/acme.

Question: where is com/acme?
You can choose the location of com/acme by using the -d option (d for destination) when compiling with javac. Assume that the current directory is called work, and the source code file Exercise1.java is to be found here. The command

javac -d . Exercise1.java

(note the dot after the -d option to indicate the current directory) will create com/acme under the current directory, and place the Java byte code for all the classes (and interface) in it.

                                  work
                                   |
                        ------------------------
                        |                      |
                  Exercise1.java              com
                                               |
                                              acme
                                               |
                                         Exercise1.class

How do we run the program? Since the current directory is work and we want to run Exercise1.class, the *full name* of the Exercise1 class must be specified in the java command:

java com.acme.Exercise1

This will now result in the main() method from the com.acme.Exercise1 class being executed.

Page 48, Numeric Type Conversions on Assignment

The following paragraph is not correct any more:

"Narrowing conversions between char and byte (or short) values on assignment always require an explicit cast, even if the value is in the range of the destination datatype."

The new rules state that a narrowing primitive conversion is valid if the following conditions are fulfilled:

1. The right-hand side expression (i.e. source) is a constant expression of type byte, short, char or int.
2. The type of the left-hand variable (i.e. destination) is  byte, short, or char.
3. The value of the constant expression is in the range of the destination datatype.

Page 68, Shift Operators: <<, >>, >>>

Replace the sentences:

"The number of bits shifted is always in the range modulus 32 for an int value, and in the range modulus 64 for a long value."

with:

"The shift distance is calculated as the value of the expression (right operand value & (size-1)), where size is either 32 or 64 depending on whether the promoted type of the left operand is int or long. Thus the shift distance is always in the range 0 to 31 when the promoted type of left operand is int, and in the range 0 to 63 when the promoted type of left operand is long."

Page 137, switch Statement

Replace the following sentence in the lower half of the page:

"The value LITTLE_ADVICE results in only one advice at (5) being given."

with:

"The value LITTLE_ADVICE results in only one advice at (4) being given."

Page 225, Table 7.1 Overview of Classes and Interfaces

Replace the last row of the table for interfaces with the following two rows:
 
Entity  Declaration Context Accessibility Modifiers Outer Instance Direct Access to Enclosing Context Defines Static or Non-static Members
Package level interface As package member public or default No N/A Static variables + non-static method prototypes
Top-level nested interface As static class member all No Static variables in enclosing context Static variables + non-static method prototypes

Page 228, Figure 7.1 Top-level Nested Classes and Interfaces

To make the figure consistent with Example 7.2, do the following:

In the figure, add public accessibility, '+', to the class AccessInTopLevelClass.

In the figure, remove public accessibility, '+', from the interface NestedTopLevelInterface1.

Page 313, Searching for Characters and Substrings

On top of the page, replace the line:

String replace(char old, char new)

with:

String replace(char oldChar, char newChar)

Page 447, Review Question 14.18

Replace the question:

"What would be the effect of calling enableEvent(AWTEvent.KEY_EVENT_MASK) on a component?"

with:

"What would be the effect of calling enableEvents(AWTEvent.KEY_EVENT_MASK) on a component?"

Page 556, Section 18.3 Byte Streams: Input Streams and Output Streams

In the middle of the page, replace the sentence:

"Note that the first read() method read a byte, but returns an int value."

with:

"Note that the first read() method reads a byte, but returns an int value."

Page 558, Searching for Characters and Substrings

In the lower half of the page, replace the line:

FileOutputStream(File file) throws IOException

with:

FileOutputStream(File file) throws FileNotFoundException

Page 568, Section 18.4 Character Streams: Readers and Writers

The paragraph:

 "Note that the read() methods read an int in the range 0 to 65535 (0x0000–0xFFFF), i.e. a Unicode character. The value –1 is returned if the end of file has been reached."

should read:

 "Note that the read() methods read Unicode characters which are 16-bit integer values in the range 0 to 65535 (0x0000–0xFFFF). The first method returns the character read as an int. The last two methods return the number of characters read into the char array. The value –1 is returned by all methods if the end of file has been reached."

Page 598, Specifying Hyperlinks to Members

To the existing list, add the following:

@see <class-name>#<member-name> <label>
@see <class-name>#<method-signature> <label>
{@link <class-name>#<member-name> <label>}
{@link <class-name>#<method-signature> <label>}

Page 625, Answer to Review Question 2.11 

Additional explanation:

Strict adherence to the Java language specification requires the following declaration to start the execution of a Java program:

public static void main(String[] args)

This does not rule out any other legal non-accessibility modifiers like final. The Java compiler is however taking liberties with the specification allowing other declarations for starting the execution of a Java program.

Page 637, Answer to Review Question 6.2 

See also the note on Inheritance of Superclass Members at the end of this errata.

Page 668, Alternate solution to Programming Exercise 3.2

public class BinConversion {
    public static void main(String args[]) {
       System.out.println(convert(43));
    }
    public static String convert(int i) {
       String res = "";
       do {
           res = i % 2 + res;
           i /= 2;
       } while (i >= 1);
       return res;
    }
}

Clarification on Inheritance of Superclass Members

On page 118 (subsection private Members), page 173 (section 6.1 Inheritance) and page 178 (review question 6.1, choice (c)), it is stated that ALL members of a superclass are inherited by the subclasses. Accessibility modifiers can be used to control whether the inherited members are accessible in the subclasses or not.

The Java Language Specification (JLS) states in section 8.2 that:
"Members of a class that are declared private are not inherited by subclasses of that class. Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.
Constructors, static initializers, and instance initializers are not members and therefore are not inherited."

According to this view, inheritance is linked to DIRECT ACCESSIBILITY of superclass members. In this sense the private members of the superclass are NOT inherited by the subclasses, but these members do EXIST in a subclass OBJECT. Private members of the superclass may be indirectly accessible from a subclass object if the superclass provides the appropriate implementation. In the example below, the private variable i in superclass A exists in object b of subclass B, but this data member is not inherited by the subclass B.

class A {
    private int i = 10; // Not inheritable
    public void printI() { // Inheritable
    System.out.println("i " + i);
    }
}

class B extends A {}

public class Inheritance {
    public static void main(String[] args) {
          B b = new B();
          b.printI();
    }
}

Output from the program:
i 10

JLS further states (section 8.4.6):

"A class inherits from its direct superclass and direct superinterfaces all the non-private methods (whether abstract or not) of the superclass and superinterfaces that are accessible to code in the class and are neither overridden (§8.4.6.1) nor hidden (§8.4.6.2) by a declaration in the class."

We will make the appropriate changes in accordance with JLS in the second edition.

Other non-essential changes

Chapter 5 Flow Control and Exception Handling

Replace all mentions of "state diagram" with the more accurate term "activity diagram".