Java 1.5 Tiger: A Developer's Notebook by David Flanagan, Brett McLaughlin The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. 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 This page was updated February 14, 2008. UNCONFIRMED errors and comments from readers: [11] First paragraph; Contrary to the first sentence, "public Point3D getLocation()" looks perfectly normal to me. Am I missing somthing, or is the code missing an annotation referred to in the last sentence: "It's accomplished through the annotation, covered in detail in Chapter 6." I don't see an annotation in the code, nor is there one in the downloadable sample code. (12) 1st Paragraph; "Basic Multilingual Plan" should read: "Basic Multilingual Plane" from http://www.unicode.org/standard/principles.html "the basic multilingual plane, or BMP for short" {15} last paragraph; "...Java has a gaping hole that Tiger finally fills -- the ability to create type- safe arrays and lists..." arrays are type-safe already [23] 2nd complete code snippet (don't count the one starting on page 22); The "Iterating Over Parameterized Types" section on page 19 explains that for/in loops will not be covered until Chapter 7. However, a for/in loop is bewilderingly tossed out there in the second code sample on page 23, with no explanation to the reader as to what it is. {27} Last paragraph before "What about..." section; Here, there's an example of an illigal cast List ints = new LinkedList(); List nums = ints; Text says: "While this may look OK at compile-time, at runtime there are simply two lists..." If the cast were legal wouldn't it be translated at compile time to something like: List ints = new LinkList(); List nums = ints; Unless I'm missing something covered in a later chapter, it seems that there would only be ONE list. (30) 1st paragraph; the sample code public interface List should be probably changed to public interface List Since it's written in next paragraph "Since you've declared the list as a List..." Or the sentence should be changed to "...List..." [31] last line and last code; The code snippet of "biggest" is wrong. The code cannot be compiled. You need to declare type variables like this: public static int biggest(Box box1, Box box2) (33) second code snippet; The paragraph between the 2 code snippets suggest that the two are equivalent, but they are not. By using as type for both arguments, snippet 2 restricts the arguments to be of exactly the same type, so sum(new Box, new Box); is legal but sum(new Box, new Box); is not. Both, however, are legal for snippet 1. So the equivanlence for snippet 1 should really be public static double sum(Box box1, Box box2) { ... for (Iterator i = box2.contents.iterator();...) } [38] The description of valueOf method and warning.; valueOf method generated by the javac compiler is a static method. Therefore there is no way of override. The description in the "WARNING" is not correct. The static vauleOf method and name method (defined in Enum class) are mirror images of each other. [45] 2nd paragraph, 2nd sentence; "the switch statement (in a different unit)..." Should it be "the if statement (in a different unit). [48-50] The explanation of Set of Nums is incorrect and example 3-5 is wrong. [49] First paragraph (after end of code listing); Sentence states "These are all features, and are all represented by powers of two." The features are not all represented by powers of two. CEDAR, AB_ROSETTE, AB_TOP_BORDER, and IL_DOTS should be represented by something like 0x08, 0x20, 0x80, 0x100. Otherwise, the bit-wise operations will fail to test for the proper feature. (50) 1st snippet of code; Change: public static EnumSet of(E e[, E e2, E e3, E e4, E e5]); to: public static EnumSet of(E e[, E e2[, E e3[, E e4[, E e5]]]]); (65) 1st paragraph; 'unboxed' should be: 'boxed' (80) 3rd and 5th code snippets; Change: out.printf("Description of object array: %s\n", obj); to: out.printf("Description of object array: %s\n", objectArray); [88] Section titled "Suppressing Warnings"; With Tiger, @SuppressWarnings annotation is not supported by the javac compiler. Therefore the section titled "Suppressing Warnings" on page 88 through page 90 should be suppressed or rewritten. [91] The paragraph after Example 6-5, 4th line; "the compiler then automatically creates member variable with the same name" is not correct, because the compiler doesn't generate such variables. [103] 3rd line in example testGetAnnotation(PrintStream out); There is no type "MethodElement" in java.lang.reflect. "MethodElement element" should be: "Method element" or "AnnotatedElement element" [117] Margin note; It's not at all clear what the margin note refers to. I can't see any reference to LinkedList in the code in Ex. 7-5, 7-6, or 7-7 that the note could refer to. (120) first code example; list is named 'wordList' but you're iterating over 'args' [121] first paragraph; The sentence "However, this rather simple task is impossible with for/in, because the variable that is used to do all the work, i, is inaccessible in a for/in loop." is completely wrong. It is easy (and IMHO better programming practice) to use for/in to accomplish this "impossible" task, as shown below. Two methods, one using a counted loop (the book's approach), the other using for/in, are presented below for comparison (and in case anyone wishes to actually test or benchmark them, as I did before writing this): public static String countedJoin(List wordList) { StringBuilder result = new StringBuilder(); for (int i = 0, len = wordList.size(); i < len; i++) { if (i < len - 1) { result.append(wordList.get(i)).append(", "); } else { result.append(wordList.get(i)); } } return result.toString(); } public static String iterableJoin(Iterable words) { StringBuilder result = new StringBuilder(); String currentSeparator = ""; for (String word : words) { result.append(currentSeparator).append(word); currentSeparator = ", "; } return result.toString(); } My issues with the book's stated position are: 1) it is factually incorrect, as the above iterableJoin(...) shows, 2) it encourages poor programming: 2a) iterableJoin(...) can be used with more argument data types (List, Set, array, etc., and ANY object that can deliver an iterator), 2b) countedJoin(...) performs very badly if the argument is a LinkedList! 2c) iterableJoin(...) is shorter, faster, and IMHO clearer. Please let me add that I have a high regard both for O'Reilly in general and for this book! It's just that this particular example is really unfortunate, both in its misinformation and its use of a wrong approach to the task at hand. {142} 3rd paragraph; Nowhere in the section called "Handling Uncaught Exceptions in Threads" does it mention that these exceptions must be "unchecked" exceptions ( derived from java.lang.RuntimeException, maybe others ). You will get compiler errors if you attempt this method with the more normally used "checked" exceptions. {146} 2nd paragraph; Thread.setUncaughtExceptionHandler(new MyDefaultHandler( )); should be Thread.setDefaultUncaughtExceptionHandler(new MyDefaultHandler( )); (153) 4th paragraph; The description of the convert method uses the word "direction" whereas the convert method's first parameter is called "duration". The description needs to be modifed to suit the parameter name. (173) Index; "(BMP) Basic Multilingual Plan" should read: "(BMP) Basic Multilingual Plane" from http://www.unicode.org/standard/principles.html "the basic multilingual plane, or BMP for short"