Java in a Nutshell, second edition by David Flanagan Most of the errata come from reader email. If an item is in the unconfirmed section and says something like "x should be y," that's the reader's opinion, not definitively the way the book should read. Send all errors or technical questions to booktech@oreilly.com. If you have any suggestions for the format of the errata pages. you can send them to mwang@oreilly.com. This page was last updated on July 8, 1998. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification Confirmed errors: (7) last paragraph, last sentence: "and it seems to reasonable to". The "to" between "seems" and "reasonable" should be removed. (8) first sentence of last paragraph, "their use [is] commonplace". (i.e., insert "is") (12) last paragraph, second to last sentence: "Recall that this these". The word "this" should be removed. (20) third bullet item from the top: "class B in different package". An "a" needs to be inserted between "in" and "different". {23} under Primitive Data Types section, line 4: Not so in Java. In C, an uninitialized local variable usually has garbage as its value. In Java, all variables have guaranteed default values, though the compiler may warn you in places where you rely, accidentally or not, on these default values. This statement is not true for Java local variables. In this case, the compiler does not just warn you. It is an error and the program should not compile. The relevant section in the Java Language Specification is 4.5.4 titled "Initial Values for Variables". The fifth bullet says: A local variable (sec 14.3, sec 14.12) must be explicitly given a value before it is used, by either initialization (sec 14.3) or assignment (sec 15.25), in a way that can be verified by the compiler using the rules for definite assignment (sec 16). The text on page 23 is wrong by asserting that the compiler merely warns rather than reject an uninitialized local variable. (reply from author) You are absolutely right. Thanks for bringing this to my attention; I thought I had corrected it already. The misinformation in my book was probably based on ambiguous wording in the original beta draft of the Java Language Specification... David {70} line 5: the statement, "static methods cannot be overridden" is not true; they can be overridden. From the author: The statement is correct; however, it could be clarified as follows: Static methods, by their very nature, are not inherited, and thus cannot be overridden. A subclass can have a static method with the same name as its superclass, and in some cases, the static method in the subclass may hide the static method in the superclass, but there is no overriding going on. (82) Sixth bullet item: "You can explictly refer". The word "explictly" should be "explicitly". (114) para. 4, line 3: "to do to" should be "do to" (158) para.1, first sentence: "In addition [to] the new". (158) para. 3, first sentence: "larger the the ScrollPane", first "the" should be "than". (175) first comment (second line on page), "array or ints" should be "array of ints". (176) para. 3, second sentence: "proided" should be "provided" (183) para. 1, fourth sentence: "...file with c option..." should read "...file with the c option..." {247} first example % jar cvf my.jar *.java images should be % jar cvf my.jar *.class images {467} Top of page: in the description of java.lang.process, the descriptions of getErrorStream and getInputStream are switched. (604) the entry for "print(), Applet class" should refer to p. 128 instead of p. 126. Unconfirmed errors: {9, 15} The prototypes of the main() method on: * p. 9 reads: public static void main(String[] args) * p.15 reads: public static void main(String args[]) The order of the identifier of "args" and "[]" is not important (as is explained later on p.32 Section "Declaring Array Vairables and Arguments"). You may want to change the order on p. 9. Next, "args" may be replaced by any other identifier (not just "argv"). An identifier is obligatory, however (note the presence of "e" as identifier in the prototypes of methods mouseDown and mouseDrag on p. 11 in Example 1-2, even though "e" is not used in the bodies of the methods). {9} Section "Hello World", first paragraph reads: "This program, like every Java program, consists of a public class definition." It came as a surprise to me that the class Huppel2 given below can be compiled with javac and run with java yielding the specified text. Hence, the behaviour of jdk1.1.5 and the descriptive text are different. class Huppel2 { public static void main( String[] args ){ System.out.println( "Huppel2 program executed..." ); } } As a next surprise, the class Huppel2 may occur on its own in a file named huppel2.java, or even huppel3.java ! {13} Example 1-3: The text "Please scribble away in the applet below." in the HTML-file is not shown in Figure 1-1. {17} I think that the line "set CLASSPATH .;C:\...." needs an equals sign, like this: set CLASSPATH=.;C:\... {23} Under Primitive Data Types section, line 5: "In Java, all variables have guaranteed default values..." But, it's an error to use uninitialized automatic variables in methods. {31} 6 line code roughly in the middle of the page. The second last line of code: triangle[i][j] = (short) i+j; should read triangle[i][j] = (short) (i+j); {31} last code line on the page reads: byte b=pixels[i+j*columns]; it should read: byte b=pixels[i*columns+j]; since i is the row # and j is the column #. ?31? "Accessing Array Elements": Please add: the first element of an array is accessed by index 0 (just like C). I do agree that Example 2-1 already suggests this (and that from the lack of this information one may defer that it is just like C). {36} the switch Statement: "You may use byte, char, short, int, or long types as the values of the case labels..." long data type may not be used either as a switch parameter or a case label. You can not use a long type in a switch statement; it will result in a compiler error. (from another reader) According to the Java Language Specification (ISBN 0-201-63451-1), section 14.9: SwitchStatement: switch ( Expression ) SwitchBlock SwitchLabel: case ConstantExpression : "The type of the Expression must be char, byte, short, or int, or a compile-time error occurs... Every case constant expression associated with a switch statement must be assignable (5.2) to the type of the switch Expression." Since type long is not assignable to int without an explicit conversion, this implies that type long is not a valid type for use in a case label. {40} Section "Exception Handling": The statements of a finally block are not executed when System.exit() is invoked ... see next program which does NOT provide the "true". This is conform the description of System.exit() on p. 15 (Section "Program Exit Value"). // // Check whether or not the finally-block is executed // in case of a System.exit() invocation. // public class CheckFinallyExecution { public static void main(String[] args) { try { System.out.println( "The finally-block is executed " + "when \"true\" is given " + "at the next line" ); System.exit(0); } finally { System.out.println( "true" ); } } } ?44? suggestions for Example 2-3: * You may like to add a "." after "Must specify an argument" in first catch. * You may like to add a "\n" somewhere to handle the argument 2 (amongst others) as desired ("i = 2MyOtherException..." is yielded now). (46) Term "signature" (used for the first time in section "Method Overloading") is lacking in the index, and not shown in italic. ?47? Within the explanation of "synchronized", it took me some time before I realized that "the instance that invoked the method" is actually an instance of the (or any sub-) class (not just an instance of another class). This is evident (from an object-oriented perspective), but may come as a surprise to C-programmers. Note that Classes and Objects are explained in the next chapter. ?50? "3.14159" is used in Example 3-1, whereas the final static PI from class Math could be used as well (and has already been introduced on p. 21 "Defining Constants"). The same holds for various other examples in the remainder of the chapter. ?52? Section "How it works", last paragraph: "method argument" is ambiguous. In Section "Using Object Methods" on p. 51, "argument" is used to identify both the actual parameter as well as the formal parameter. It is clear from the context what is meant there. On p. 52, "method argument" shall be interpreted as "the identifier (or name) of the formal parameter". (52) Section "Object Creation": Java gives us a default constructor if and only if we don't define our own. Hence, the next example is illegal: // Check whether or not Java gives us a default constructor // whenever we define at least one ourselves. public class CheckDefaultConstructor { public static void main(String[] args) { Circle c = new Circle(); // illegal: Circle() is not defined System.out.println( "Construction of Circle c with default constructor" ); } } class Circle { public double x, y, r; public Circle( double x, double y, double r) { this.x = x; this.y = y; this.r = r; } } (55,63) Section "An Example", Example 3-4: unlike most definitions given so far, "num_circles" is not defined using the keyword "public". It is not wrong (but surprising). As a consequence of this ommision, the sentence "Thus, we might write" in Section "Accessing Class Variables" on the same page is incomplete, because classes in other packages can not access the variable (according to Table 3-1 on page 73). The same holds for "Color outline, fill;" in Example 3-10 on page 63. (57) Section "No this" states that System is another class that defines only class methods. Because "Every class in Java has at least one constructor method,..." (p. 52 Section "Object Creation") something must have been done within the class System to prevent unintended object-creation... The explanation is found in Section "The Default Constructor", last paragraph, top of p. 67. (59) Example 3-6: You may like to explain the usage of "private" in the declarations of the class variables. The keyword has been introduced already on p. 19, and its rules are explained in depth in Table 3.1. (59) Last paragraph: "native methods - i.e., methods written in C". The "i.e." shall be replaced by "e.g.". (65) Section "Constructor Chaining", first sentence, "the class's" shall be replaced by "a class's". {73} 4th paragraph, how could the method f() and variable x in instance c be accessible to its super class b? ?73? Please provide example code explaining the fourth paragraph. I was unable to write a java program exemplifying the description (and yielding the complete behaviour, in particular the usage of c, as described).> {73} In addition to the explanations given, you may like to add that "Methods can't be overridden to be more private." An example is given below. // // Check whether or not the accessibility of overriding methods of // sub-classes need to be identical to those of their super-class. // It turns out that (error message from javac): // "Methods can't be overridden to be more private." // class Super { private void method1() {} /* package */ void method2() {} protected void method3() {} public void method4() {} } // more stringent (i.e. more private) sub-class: class Sub1 extends Super { private void method2() { super.method2(); } // error /* package */ void method3() { super.method3(); } // error protected void method4() { super.method4(); } // error } // less stringent sub-class: class Sub2 extends Super { /* package */ void method1() { super.method1(); } protected void method2() { super.method2(); } public void method3() { super.method3(); } } (74) You may like to add "static" in the declaration of check_radius in Example 3-14. (79) Section "Implementing Multipe Interfaces": "Drawable" is redundant in the implements clause, because DrawableScalableRectangle extends DrawableRectangle, and DrawableRectangle implements Drawable. You may like to replace "DrawableRectangle" by "Rectangle" (in order to keep the remark concerning the comma-separated interfaces in the implements clause). {82} 9th item: An abstract class need not contain abstract methods (as explained on on p. 75, Section "Abstract Classes", 2nd item). > {104} The text refers to a "static" keyword in the example which isn't there. Either the example should be changed to include a "static" keyword or the text should be changed to consistently emphasize that the static declaration is implicit. {155-156} The top paragraph on p. 156 (which begins on p. 155) could be made clearer by saying: All components recieve events regardless of whether they are listening for them or not (via enableEvents() or actionListeners.) Events are not *dispatched* to listeners if those events are not enabled. But they ARE recieved by the component. So another way to get them is: 1) DO NOT add listeners or enableEvents() 2) Override dispatchEvent() to get to your event anyway. {181} This isn't really an error, but the MultiLineLabel JavaBean doesn't recognize consecutive newlines, because of the way a StringTokenizer works. Workaround: put spaces between consecutive newlines. {298} In the description of java.awt.Dialog. The sentence on "show()" should read: "Call show() to pop a dialog up and setVisible(false) to pop it down." {358} In the desription of java.awt.event.WindowEvent, under "WINDOW_CLOSED", "destroy()" should read "dispose()" (438) Actually, this is a more general complaint, but an example of what the reader means can be seen on this page. A reader notes that it's difficult to tell the difference between l (small el) and I (capital i) in the font we use for class definitions. (see "eolIsSignificant" on this page) {462} The final class Math says // No constructor It does have a private constructor (which disallows instantiation). private Math() {} {467} Top of page in the description of java.lang.Process. The sentence on getInputStream should read "...read any bytes the process sends to its standard output stream." The sentence on getErrorStream should read "...read any bytes the process sends to its standard error stream."