Errata for Object-Oriented Software Development Using Java by Xiaoping Jia, 2nd ed.

Errors

The textbook for the course (Object-Oriented Software Development Using Java by Xiaoping Jia, 2nd ed.) has a number of errors. These errors were found in the first printing.

p. 12
The word ``not'' should be inserted in ``..., the goal here does not involve establishing the complete requirements of the system.''
p. 84
The first three table results are incorrect, and it would be less confusing if all results were given as strings. The corrected table reads
Expression Result
"object" + "-" + "oriented" "object-oriented"
"object" + '-' + "oriented" "object-oriented"
"Mail Stop" + 205 "Mail Stop205"
123 + ' ' + "Oak Street" "123 Oak Street"

p. 94
The text for ``Expression statements'' is correct, but the examples lead one to believe that object creations cannot be made expression statements directly, but instead need to be embedded in assignments. In Java, it is perfectly legal to write:

new Point();
However, unless the constructor has some side-effect, such a construction has no interesting effect.

p. 97
The for loop is more closely equivalent to
{
   
InitExpr;
   while (
Condition ) {
      
Statement
      
IncrExpr;
   }
}
In other words, the scope of the
InitExpr
is only the loop, it does not extend to the later staements in the block in which the for loop is embedded.

p. 97
In the code for class Sum, the braces around the elements of array a are inadvertently omitted. The code should read:
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

p. 138
The text twice refers to classdir when it should refer to srcdir. Furthermore, the compilation of Maximum.java should use javac, not java, and thus should read:
venus% javac xj/num/Maximum.java

p. 141f
IndexOutOfBoundsException is spelled wrong twice (missing s)

p. 150
The variable clockThread should be volatile or else this variable read could be optimized.

p. 151
The line from DigitalClock.run()
Thread.currentThread().sleep(1000);
is confusing since the sleep method is static. It is better written as:
Thread.sleep(1000);

p. 152
Calendar is not a singleton class.

p. 161
The class name Point must be inserted into the code
Point p2 = new Point(20.0, 30.0); // invoke Point(double,double)

p. 167
In the first paragraph, it's unclear why "compatibility" is being defined here, and the definition may be nonstandard.

p. 168
At the bottom of the page, the statement ``Java allows explicit casting of any reference type to any other reference type.'' must be qualified with ``unless the types are provably disjoint.'' In other words, if the compiler can prove that the only value the two types have in common is null, then the cast will be rejected at compile-time.

p. 170
The diagram at the bottom of the page should have double[] as a class instead of double. The primitive type double is not a subclass of Object.

p. 172
The example with B and C is legal Java, despite what the book says. In Java, m3 is overloaded in class C. (The textbook is correct that in C++, the inherited signature is hidden.)

p. 183
The definition of class MyClass incorrectly repeats the keyword public. Furthermore, method4 cannot implement the methods in the two interfaces because it throws more exceptions. Overriding methods must throw a subset of the overridden method's exceptions.

p. 200
The URL in the example mistakenly includes a space after the double slash.

p. 207f
The three sentences starting ``If an auxiliary class supports a single public class,'' and then going on to the next page should be replaced with the following:
If an auxiliary class supports a single class (public or auxiliary), it may reside in the same file as the class it supports. If an auxiliary class supports multiple classes in different files, it must reside in a separate file.

p. 224
In the ``Design Guideline'' for preserving invariants, it should be noted that public and private methods have an obligation to (re-)establish the invariant before calling any public method. And then of course, they can assume the invariant is true when the public method returns.

p. 230
The use of bitwise-or recommended for computing hash values doesn't work well when more than 4 items are combined, in which case none of the earlier items make a contribution to the final value. Furthermore, the use of bitwise-or and a non-zero c unnecessarily loses information. Much better would be to use exclusive-or (the ^ operation).

p. 264
The call super.update() is missing the parameter g, and thus will not compile. (The offending line is commented out in the code distributed with the book.)

p. 282
The description of method remove() is wrong: it removes the previous element of the list and does not advance the current position.

p. 356
Figure 8.13 incorrect uses JPenel for JPanel.

p. 357
The constructor for BouncingBall3 uses a deprecated interface. Instead of:     add("Center", canvas);
    
    add("South", controlPanel);
it should instead have:     add(canvas, BorderLayout.CENTER);
    
    add(controlPanel, BorderLayout.SOUTH);

p. 383
Incorrect typography (fonts) makes the paragraph in the middle of the page confusing. It refers to "8859_1," and "GB2312." Instead it should say ``8859_1,'' and ``GB2312.''

p. 485
In the figure describing the ABSTRACTFACTORY design pattern, the abstract class is misnamed AbstractFactor (missing ``y''), and the upper abstract product class should be named AbstractProductA (missing ``A'').

Let me know of any other errors you suspect.

Java 5 Changes

The latest major release of Java (JDK 5) introduced a number of core language changes. Here I list them giving the relevant page number in the textbook where they would be discussed if the textbook were updated to reflect JDK 5:

p. 97
There is a new loop syntax in addition to the C/C++ style for loop:
for ( Type id : expr) {
   ...
}
This implicitly iterates over all the elements in the collection resulting from evaluating expr.
p. 101
Class declarations can have formal type parameters:
< TypeFormal,..., TypeFormal>
where each type formal gives a name and optionally an upper or lower type bound (using extends or super, respectively).

In a use of a parameterized class. it is best to give the actual type parameters. If you do not, the system will infer a ``raw'' type for you but these types are not recommended because they can lead to type unsoundness not caught until run-time.

Classes (and indeed all declarations, including methods and fields) may be annotated with @modifier annotations.

p. 102
The same syntax can be used as a method modifier to give formal type parameters to a method or constructor. It is not required to give the actual type parameters if the compiler can infer them. In any case, specifying the actual type parameters uses an awkward syntax: they come before the method name.
p. 110
Static members of a class cannot use the formal type parameters of the class.
p. 117
Interfaces may have type parameters as well.
p. 129
Construction of instances of wrapper class are inserted automatically by the compiler when needed. It is normally not necessary to explicitly construct an instance of a wrapper class. Similarly, these objects are implicitly unwrapped when needed. This implicit unwrapping may throw a NullPointerException if the wrapper object is actually null.
p. 171
It is now conventional to mark overriding methods with the annotation @Override to signify intent to override.
p. 308
Section 8.2 describes the collection classes. In Java 5, all the classes are now parameterized. If you omit the type parameters, you will be using ``raw'' types, which will lead to warnings. The advantage of the type parameters is that much less downcasting is required when using the collection classes.
p. 465
Java 5 introduced enumeration types which obsolete section 10.1. The example in section 10.1.3 can be written:
enum Orientation { VERTICAL, HORIZONTAL } ;
All enum types are implicitly ordered, and thus the example from 10.1.4 can be written:
enum Direction { NORTH, EAST, SOUTH, WEST };
Instead of using first and next (as on page 470), one would use the new for loop syntax as in:
for (Direction d : Direction.values()) {
  //
process each direction
}

John Tang Boyland
2005-10-03