Catalog of Traps and Pitfalls
Have you done the puzzles yet? If not, go to Chapter 1! Go directly to Chapter 1. Do not pass GO. Do not collect $200. If you read this chapter before doing the puzzles, it will take all the fun out of the book. Don’t say we didn’t warn you.
This chapter contains a concise taxonomy of traps and pitfalls in the Java plat- form. Each entry in the catalog is divided into three parts:
A short description of the trap or pitfall
Prescription: How to avoid the trap or reduce the risk of falling victim.
References: Pointers to additional information concerning the trap. This typically includes a reference to the puzzle that is based on the trap. Many entries also have Java Language Specification and Effective Java refer- ences [JLS, EJ].
239
240 Appendix A • Catalog of Traps and Pitfalls
1. Lexical Issues
This section concerns the lexical structure of Java programs: the tokens that make up programs and the characters that make up tokens.
1.1. The letter el looks like the digit 1 in many fonts Prescription: In long literals, always use a capital el (L), never a lowercase el (l).
Do not use a lone el (l) as a variable name. References: Puzzle 4.
1.2. Negative hex literals appear positive
Prescription: Avoid mixed-type computation; use long literals instead of int lit- erals where appropriate.
References: Puzzle 5; [JLS 3.10.1].
1.3. Octal literals look like decimal literals
Prescription: Avoid octal literals. If you must use them, comment all uses to make your intentions clear.
References: Puzzle 59; [JLS 3.10.1].
1.4. Unicode escapes for ASCII characters are confusing
Prescription: Don’t use Unicode escapes for ASCII characters. Where possible, use ASCII character directly. In string literals and character literals, prefer escape sequences to Unicode escapes.
References: Puzzles 14, 16, and 17; [JLS 3.2, 3.3].
1.5. Backslashes must be escaped, even in comments
Prescription: If you are writing a system that generates Java source code, escape backslashes in generated character literals, string literals, and comments. Win- dows filenames are a common source of trouble.
References: Puzzles 15 and 16; [JLS 3.3].
Appendix A • Catalog of Traps and Pitfalls 241 1.6. Block comments do not nest
Prescription: Use single-line comments to comment out code. References: Puzzle 19; [JLS 3.7, 14.21].
2. Integer Arithmetic
This section concerns arithmetic on the integral types: byte, char, short, int, and long.
2.1. Nonzero result of % operator has sign of left operand Prescription: If you need a nonnegative remainder, process the result of the %
operator by adding the modulus if the result is negative. References: Puzzles 1 and 64; [JLS 15.17.3].
2.2. Integer arithmetic overflows silently
Prescription: Use types that are sufficiently large to hold results, including inter- mediate results.
References: Puzzles 3, 26, 33, and 65; [JLS 4.2.2].
2.3. The sign of the difference of int values does not
reliably indicate their order
Prescription: Do not use a subtraction-based comparator unless you are sure that the difference between values will never be greater than Integer.MAX_VALUE. Note that this is a special case of Trap 2.2.
References: Puzzle 65; [EJ Item 11].
242 Appendix A • Catalog of Traps and Pitfalls
2.4. Compound assignment operators can cause silent
narrowing cast
Prescription: Don’t use compound assignment operators on variables of type byte, short, or char.
References: Puzzles 9 and 31; [JLS 15.26.2].
2.5. Integral types are asymmetric: Integer.MIN_VALUE
is its own negation, as is Long.MIN_VALUE Prescription: Program defensively. Use long instead of int if necessary.
References: Puzzles 33 and 64; [JLS 15.15.4].
2.6. Shift operators use only the low-order bits of their
right operand
Prescription: Shift by a constant amount; if you must shift by a variable amount, check that the shift distance is in range.
References: Puzzle 27; [JLS 15.19].
2.7. When converting between integral types, sign
extension is performed if the source type is signed
Prescription: Be careful when working with byte values, which are signed. To suppress sign extension, use a bit mask.
References: Puzzle 6; [JLS 5.1.2].
3. Floating-Point Arithmetic
This section concerns arithmetic on the floating-point types: float and double. 3.1. Floating-point arithmetic is inexact
Prescription: Don’t use floating-point where exact results are required; instead, use an integral type or BigDecimal.
Avoid floating-point loop indices.
Avoid using the ++ and -- operators on floating-point variables, as these operators have no effect on most floating-point values.
Avoid testing floating-point values for equality.
Prefer double to float.
References: Puzzles 2, 28, and 34; [JLS 4.2.3], [EJ Item 31], and [IEEE-754].
3.2. NaN is not equal to any floating-point value, including itself
Prescription: Avoid testing floating-point values for equality. This is not always sufficient to avoid problems, but it’s a good start.
References: Puzzle 29; [JLS 15.21.1] and [IEEE-754].
3.3. Conversions from int to float, long to float, and
long to double are lossy
Prescription: Avoid computations that mix integral and floating-point types. Pre-
fer integral arithmetic to floating-point. References: Puzzles 34 and 87; [JLS 5.1.2].
3.4. The BigDecimal(double) constructor returns the exact value of its floating-point argument
Prescription: Always use the BigDecimal(String) constructor; never use BigDecimal(double).
References: Puzzle 2.
Appendix A • Catalog of Traps and Pitfalls 243
244 Appendix A • Catalog of Traps and Pitfalls
4. Expression Evaluation
This section concerns aspects of expression evaluation that are not specific to inte- ger or floating-point arithmetic.
4.1. Mixed-type computations are confusing
Prescription: Avoid mixed-type computations.
When using the ? : operator with numeric operands, use the same numeric type
for both the second and third operands.
Prefer constant variables to inline magic numbers. References: Puzzles 5, 8, and 24.
4.2. Operands of operators are evaluated left to right
Prescription: Avoid multiple assignments to the same variable in the same expression. Especially confusing are multiple compound assignment operators in the same expression.
References: Puzzles 7, 25, and 42; [JLS 15.7] and [EJ Item 37]. 4.3. Operator precedence is not always obvious
Prescription: Use parentheses, not white space, to make precedence explicit. Replace inline constant expressions with named constant variables.
References: Puzzles 11, 35, and 95.
4.4. Operators == and != perform reference comparisons
on boxed primitive types
Prescription: To force a value comparison, assign or cast one operand to the appropriate primitive type before comparing.
References: Puzzle 32; [JLS 15.21, 5.1.8].
Appendix A • Catalog of Traps and Pitfalls 245 4.5. Constant variables are inlined where they are used
Prescription: Avoid exporting constant fields unless they represent true constants that will never change.
Use an identity method to make an expression nonconstant. References: Puzzle 93; [JLS 4.12.4, 13.1, 15.28].
4.6. Operators & and | evaluate both operands even when used on boolean values
Prescription: Avoid the & and | operators for boolean operands. Document any intentional uses.
References: Puzzle 42; [JLS 15.22.2, 15.24].
5. Flow of Control
This section concerns statements that affect flow of control, and exceptions.
5.1. Missing break in switch case causes fall-through Prescription: Don’t fall through from one nonempty case to another: Terminate
each nonempty case with a break. Document any intentional fall-throughs. References: Puzzle 23; [JLS 14.11].
5.2. It is difficult to terminate an int-indexed loop at Integer.MAX_VALUE
Prescription: To terminate an int-indexed loop at Integer.MAX_VALUE, use a long loop index or write the loop very carefully.
References: Puzzle 26.
246 Appendix A • Catalog of Traps and Pitfalls
5.3. Abrupt completion of a finally block masks
pending transfer of control
Prescription: Ensure that every finally block completes normally, barring a fatal error. Do not return from or throw an exception from a finally block.
References: Puzzles 36 and 41; [JLS 14.20.2].
5.4. Using exceptions for normal control flow leads to
bugs and poor performance
Prescription: Use exceptions only for exceptional cases, never for normal control flow.
References: Puzzle 42; [EJ Item 39].
6. ClassInitialization
This section concerns class loading and initialization.
6.1. Order of class initialization is top to bottom
Prescription: Ensure that static fields are initialized in an appropriate order. Use lazy initialization to resolve initialization cycles, which can involve one or more classes.
References: Puzzles 49 and 52; [JLS 12.4.2] and [EJ Item 48].
6.2. Timing of NoClassDefFoundError is unreliable
Prescription: Do not catch NoClassDefFoundError. Instead, use reflection and catch ClassNotFoundException.
More generally, don’t catch Error or its subclasses. References: Puzzle 44; [JLS 12.2.1].
7. Instance Creation and Destruction
This section concerns constructors, pseudoconstructors, instance initialization, and finalization.
7.1. Instance initializers execute before constructor body
Prescription: If a self-typed instance field causes recursion during construction, ensure that the recursion terminates.
References: Puzzle 40; [JLS 12.5].
7.2. Invoking an overridden method from a constructor
causes method to run before instance is initialized
Prescription: Never invoke an overridable method from a constructor. Use lazy initialization to resolve initialization cycles.
References: Puzzle 51; [EJ Items 15 and 48].
7.3. Failure to null out references can cause memory leaks
Prescription: Null out obsolete object references in long-lived objects. Failure to do so results in memory leaks, more properly known as unintended object reten- tions in garbage-collected languages, such as Java.
References: [EJ Item 5].
7.4. Failure to add a private constructor makes a class
instantiable
Prescription: If you want a class to be uninstantiable, add a private constructor. More generally, always provide at least one constructor; never depend on the
default constructor. References: [EJ Item 3].
Appendix A • Catalog of Traps and Pitfalls 247
248 Appendix A • Catalog of Traps and Pitfalls
7.5. Finalizers are unpredictable, dangerous, and slow
Prescription: Avoid finalizers. References: [EJ Item 6].
7.6. Cloned objects can share internal state
Prescription: Avoid implementing Cloneable. If you implement it, copy any internal objects that you do not want to share between the object and its clone.
References: [EJ Item 10].
8. Other Class- and Instance-Related Topics
This section concerns method invocation, method design, class design, and generic types.
8.1. There is no dynamic dispatch on static methods
Prescription: Never qualify a static method invocation with an expression; always use a type.
References: Puzzle 48; [JLS 15.12.4.4].
8.2. Inner classes are confusing
Prescription: Prefer static member classes to inner classes. References: Puzzles 80, 89, 90, and 92; [EJ Item 18].
8.3. Failure to make defensive copies destroys immutability
Prescription: Make defensive copies of input parameters and output values as required.
References: [EJ Item 24].
Appendix A • Catalog of Traps and Pitfalls 249 8.4. Implementing an interface affects the API of the
implementing class
Prescription: Do not implement an interface to gain unqualified access to its static fields.
Do not write an interface consisting solely of fields, a so-called constant interface. In release 5.0 and later releases, use static import as a replacement for the Con-
stant Interface antipattern.
References: [EJ Item 17] and [Java-5.0].
8.5. Using int constants as enum values is unsafe Prescription: Use enum types or, if you are using a release before 5.0, implement
Typesafe Enums. References: [EJ Item 21].
8.6. Mixing raw and parameterized types weakens type checking
Prescription: Eliminate “unchecked” warnings reported in your code.
Avoid using raw types in code intended for use with release 5.0 or a later release. References: Puzzle 88; [JLS 4.8].
8.7. Returning null instead of a zero-length array or collection is error prone
Prescription: Don’t return null from an array- or collection-returning method. References: [EJ Item 27].
250 Appendix A • Catalog of Traps and Pitfalls
9. Name Reuse
This section concerns the many forms of name reuse possible in Java. The overrid- ing prescription is: Avoid name reuse except for overriding. See also “A Glos- sary of Name Reuse” on page 180.
9.1. It is easy to overload when you intend to override
Prescription: Mechanically copy the declaration of each superclass method that you intend to override; better yet, let your IDE do it for you.
If you are using release 5.0 or a later release, use the @Override annotation. References: Puzzle 58.
9.2. Overload-resolution rules are not obvious
Prescription: Avoid overloading.
Provide static factories rather than multiple constructors.
If two methods in your API are both applicable to some invocation, ensure that both methods have the same behavior on the same actual arguments.
References: Puzzles 11, 46, and 74; [JLS 15.12.2] and [EJ Items 1 and 26]. 9.3. Programs that hide entities are difficult to
understand
Prescription: Avoid hiding.
References: Puzzles 66, 72, 73, and 92; [JLS 8.3, 8.4.8.2, 8.5].
9.4. Programs that shadow entities are difficult to understand
Prescription: Avoid shadowing.
Do not reuse names from java.lang.Object in public APIs. Don’t try to use static import on a name that is already defined. References: Puzzles 71, 73, 79, and 89; [JLS 6.3.1, 15.12.1].
Appendix A • Catalog of Traps and Pitfalls 251 9.5. Programs that obscure entities are difficult to
understand
Prescription: Avoid obscuring. Obey the naming conventions. References: Puzzles 68 and 69; [JLS 6.3.2, 6.5.2, 6.8] and [EJ Item 38].
9.6. A method with the same name as its class looks like a constructor
Prescription: Obey the naming conventions. References: Puzzle 63; [JLS 6.8] and [EJ Item 38].
9.7. Programs that reuse platform class names are difficult to understand
Prescription: Avoid reusing platform class names, and never reuse class names from java.lang.
References: Puzzle 67.
10. Strings
This section concerns character strings.
10.1. Arrays do not override Object.toString
Prescription: For char arrays, use String.valueOf to obtain the string repre- senting the designated sequence of characters. For other types of arrays, use Arrays.toString or, prior to release 5.0, Arrays.asList.
References: Puzzle 12; [JLS 10.7].
252 Appendix A • Catalog of Traps and Pitfalls
10.2. String.replaceAll takes a regular expression as
its first argument
Prescription: Ensure that the argument is a legal regular expression, or use String.replace instead.
References: Puzzle 20.
10.3. String.replaceAll takes a replacement string as
its second argument
Prescription: Ensure that the argument is a legal replacement string as defined in the java.util.regex specification, or use String.replace instead.
References: Puzzle 21.
10.4. Repeated string concatenation can cause poor
performance
Prescription: Avoid using the string concatenation operator in loops. References: [EJ Item 33].
10.5. Conversion of bytes to characters requires a charset
Prescription: Always select a charset when converting a byte array to a string or char array; if you don’t, the platform default charset will be used, leading to unpredictable behavior.
References: Puzzle 18.
10.6. Values of type char are silently converted to int, not
String
Prescription: To convert a char to a string, use String.valueOf(char). References: Puzzles 11 and 23; [JLS 5.1.2].
11. I/O
This section concerns the package java.io.
11.1. Stream.close can throw IOException
Prescription: Catch and, typically, ignore exceptions on close. References: Puzzle 41.
11.2. PrintStream.write(int) doesn’t flush output streams
Prescription: Avoid PrintStream.write(int). If you use it, call flush as required.
References: Puzzle 81.
11.3. Consume the output of a process, or it may hang
Prescription: Always consume the output of processes you create. References: Puzzle 82.
12. Threads
This section concerns multithreaded programming. Multithreaded programming is difficult! The overriding prescription is: Avoid low-level multithreaded pro- gramming where possible. Instead, use higher level multithreaded abstractions, such as those introduced by java.util.concurrent in release 5.0. This is an important special case of the advice in Trap 15.5.
12.1. Calling Thread.run doesn’t start a thread
Prescription: Never call Thread.run. References: Puzzle 76.
Appendix A • Catalog of Traps and Pitfalls 253
254 Appendix A • Catalog of Traps and Pitfalls
12.2. Library classes may lock or notify their instances
Prescription: Don’t use an instance lock if you extend a library class. Instead, use a separate lock object stored in a private field.
References: Puzzle 77; [EJ Item 15].
12.3. Thread.interrupted clears the interrupted status
Prescription: Don’t use Thread.interrupted unless you want to clear the inter- rupted status of the current thread. Use Thread.isInterrupted to check the sta- tus without changing it.
References: Puzzle 84.
12.4. Class initialization runs with the Class lock held
Prescription: To avoid the risk of deadlock, never wait for a background thread during class initialization.
References: Puzzle 85; [JLS 12.4.2].
12.5. Failure to synchronize when sharing mutable state
can result in failure to observe state changes
Prescription: Synchronize access to shared mutable state. References: [EJ Item 48].
12.6. Invoking alien method from within a synchronized block can cause deadlock
Prescription: Never cede control to an alien method from within a synchronized method or block.
References: [EJ Item 49].
12.7. Invoking wait outside of a while loop causes
unpredictable behavior
Prescription: Never invoke wait outside a while loop. References: [EJ Item 50].
Appendix A • Catalog of Traps and Pitfalls 255 12.8. Depending on the thread scheduler may result in
erratic and platform-dependent behavior
Prescription: To write robust, responsive, portable multithreaded programs, ensure that few threads are runnable at any given time.
References: [EJ Item 51].
13. Reflection
This section concerns Java’s core reflection APIs.
13.1. Reflection checks access to the entity and to its class
Prescription: Use reflection to instantiate classes; interfaces to access instances. References: Puzzle 78; [EJ Item 35].
13.2. Reflectively instantiating an inner class requires an extra argument
Prescription: Don’t use reflection on inner classes. Prefer static member classes to inner classes. References: Puzzle 80; [JLS 13.1] and [EJ Item 18].
13.3. Class.newInstance can throw undeclared checked exceptions
Prescription: Use java.lang.reflect.Constructor.newInstance instead of Class.newInstance if there is any possibility of the constructor throwing a checked exception.
References: Puzzle 43.
256 Appendix A • Catalog of Traps and Pitfalls
14. Serialization
This section concerns Java’s object serialization system.
14.1. Making a class serializable introduces a public pseudoconstructor
Prescription: Think twice before making a class serializable. Think twice before accepting the default readObject method. Write readObject methods defensively.
References: [EJ Items 54 and 56].
14.2. The serialized form is a part of a class’s public API
Prescription: Design serialized forms with the same care that you would design any other API.
References: [EJ Items 54 and 55].
14.3. Using the default serialized form leaks private fields
into a class’s public API
Prescription: Consider using a custom serialized form. References: [EJ Item 55].
14.4. Using the default serialized form can cause poor performance
Prescription: Consider using a custom serialized form. References: [EJ Item 55].
Appendix A • Catalog of Traps and Pitfalls 257 14.5. Maintaining instance-control invariants requires a
readResolve method
Prescription: Always write a readResolve method for singletons, handwritten
Typesafe Enums, and other instance-controlled instantiable classes. References: Puzzle 83; [EJ Items 2 and 57].
14.6. Failure to declare a serial version UID causes fragility
Prescription: Declare an explicit serial version UID in serializable classes. References: [EJ Items 54 and 55].
14.7. If readObject or readResolve invokes overridable methods, deserializing cyclic object graphs can cause corruption
Prescription: If a HashSet, HashMap, or Hashtable will be serialized, ensure that its contents do not refer back to it.
In readObject and readResolve methods, avoid invoking methods on objects currently being deserialized. If you must violate this advice, ensure that no prob- lematic cycles exist in the object graph.
References: Puzzle 91.
15. OtherLibraries
This section concern various Java platform libraries.
15.1. Overriding equals without overriding hashCode can cause erratic behavior
Prescription: When overriding equals, always override hashCode. References: Puzzle 57; [EJ Item 8].
258 Appendix A • Catalog of Traps and Pitfalls
15.2. Calendar and Date are poorly designed
Prescription: Be careful when using Calendar and Date; always consult the API documentation.
References: Puzzle 61.
15.3. Many classes are immutable, their method names
notwithstanding
Prescription: Do not be misled into thinking that immutable types are mutable. Immutable types include String, Integer, Long, Short, Byte, Character, Boolean, Float, Double, BigInteger, and BigDecimal.
References: Puzzle 56.
15.4. Some deprecated methods are toxic
Prescription: Avoid deprecated methods, such as Thread.stop, Thread.suspend, Runtime.runFinalizersOnExit, and System.runFinalizersOnExit.
References: Puzzle 39 and 43; [ThreadStop].
15.5. Using homemade solutions instead of libraries tends
to cause wasted effort, bugs, and poor performance
Prescription: Know and use the libraries. References: Puzzles 60, 62, and 94; [EJ Item 30].
B
Notes on the Illusions
This appendix contains brief descriptions of the illusions that appear throughout the book. The descriptions are grouped loosely by category. Within each category, the order is roughly chronological.
Ambiguous Figures
An ambiguous figure is a drawing that can be seen in two or more ways, though not at the same time. One kind of ambiguous figure is a two-dimensional drawing that can be seen to represent one of several different three-dimensional figures. The Ambiguous Cube (page 67) can be seen in three ways: as a large cube with a small cubic region missing from one corner, as a small cube sitting inside a corner of a larger one, and as a large cube with a small cube protruding from one corner.
Another kind of ambiguous figure is the figure-ground illusion, which is a drawing that can be seen in two ways, depending on what you perceive as the fig- ure and what you perceive as the background. The drawings on pages 158 and 231 can be seen as black arrows pointing outward against a white background, or as white arrows pointing inward against a black background. The drawing on page 97 can be seen as white letters against a black background, or as black shapes against a white background.
259
260 Appendix B • Notes on the Illusions Impossible Figures
An impossible figure is a two-dimensional perspective drawing of a figure that cannot exist in three dimensions. The arrangement of cubes on page 122 is based on an impossible figure drawn by Swedish artist Oscar Reutersvärd in 1934. This drawing is thought to be the first impossible figure ever devised. Reutersvärd devoted his career to impossible figures.
The Penrose Triangle (pages 36 and 126) is closely related to Reutersvärd’s triangle of cubes, but it was created independently by physicist Roger Penrose in 1954. The Penrose Stairway (page 63) was created in the mid 1950s by geneticist and psychiatrist Lionel Penrose, the father of Roger Penrose. The Penrose stair- way forms the basis of M. C. Escher’s famous lithograph Ascending and Descend- ing (1960).
The Three-Stick Clevis (pages 59 and 200) is also known by many other names, such as Widgit, Poiuyt, and Impossible Trident. Its origins are unknown, but it dates back at least to 1964, when D. H. Schuster wrote an article about it in the American Journal of Psychology. The clevis also graced the cover of the March 1965 issue of MAD Magazine, held aloft by a smiling Alfred E. Neuman. The Ambihelical Hex Nut (pages 154 and 249) and the Impossible Ring (pages 109 and 164) are two more impossible figures of unknown origin.
Geometrical Illusions: Size
The Jastrow illusion (page 85) was described by psychologist Joseph Jastrow in 1891. The two shaded areas are identical in size and shape, but most people per- ceive the top one to be smaller. The Ebbinghaus (or Titchener) illusion (page 137) was described by psychologist Hermann Ebbinghaus in 1897. The two central cir- cles are the same size, but most people perceive the one on the right to be smaller.
The Shepard illusion (page 93) is based on a 1990 drawing by Stanford psy- chologist Roger Shepard [Shepard90]. The two tabletops are the same size and shape, but perspective cues make them look very different. Shepard first demon- strated the effect in 1981.
Geometrical Illusions: Direction
The Twisted Cord illusion (pages 13 and 221), also known as the Fraser figure, was described by psychologist James Fraser in 1908. The letters “CAFE babe” on page 13 are set straight and true; the perceived tilt is illusory. What appears to be a
tilted “Square Spiral” on page 221 is in fact eight concentric squares, set straight and true.
The Ehrenstein illusion (page 35) was described by psychologist Walter Ehrenstein in 1925. The sides of the square are straight, but they appear to curve towards the center of the circles.
The Café Wall illusion (page 39) was first demonstrated by Fraser in 1908, and named by Richard L. Gregory and Priscilla Heard [Gregory79]. The lines of black and white tiles appear slanted but they are perfectly level. The illusion gets its name from the fact that it was found in a tile pattern on the wall of a café in Bristol, England.
The Cushion illusion (page 65) was devised by vision scientist and artist Akiyoshi Kitaoka in 1998. This drawing consists solely of rectangles and squares, set straight and true; the curvature is all in your mind. If you find this hard to believe, you can confirm it with a straightedge. The Bulge illusion (page 152) and the Checkered Flag illusion (page 169) were also devised by Kitaoka in 1998. They consist solely of squares, set straight and true; the bulging and rippling are in your mind. All three of these illusions are based on the same underlying effect.
The Turtles illusion (page 225) was devised by Kitaoka in 2002. The vertical edges appear tilted but they run straight up and down. The underlying effect, known as the illusion of Fringed Edges, was described by Kitaoka, Pinna and Brelstaff [Kitaoka01].
Subjective Contours
A subjective contour, also known as an illusory contour, is a perceived edge that does not exist. The classic example is found in the Kanizsa Triangle (pages 146 and 242), devised by Gestalt psychologist Gaetano Kanizsa in 1955. A white tri- angle appears to float above a black triangular outline, but the lines that form the white triangle don’t exist. Your mind constructs them from the contours implied by the “Pac-Man” figures. The variant on page 147 is based on a figure devised by Branka Spehar [Spehar00], and the variant on pages 15 and 168 is based on a fig- ure devised by Takeo Watanabe and Patrick Cavanagh [Watanabe92]. The three- dimensional variants on pages 100 and 101 are based loosely on the Subjective Necker Cube of Bradley and Petry, discussed later in this appendix. The Kanizsa Dot Window on page 69 is based on a figure drawn by Kanizsa in 1979.
The Shadow Letters on page 27 are also a subjective contour illusion. Your mind perceives the letters A, B, and C, when all that is present is the shadows that these letters would cast.
Appendix B • Notes on the Illusions 261
262 Appendix B • Notes on the Illusions Anomalous Motion Illusions
Anomalous motion illusions are drawings whose components appear to move. The MacKay’s Rays illusion (page 203) was described by Donald MacKay in 1957. Figure-eight patterns appear to move about the drawing as you scan over it with your eyes. The drawings on pages 47, 192, and 230 are based on the MacKay’s Squares illusion, described by MacKay in 1961. The figure appears to blink as you look at it. This illusion forms the basis of Reginald Neal’s op art prints Square of Three (1964) and Square of Two (1965).
The Ouchi illusion (page 173) was devised by artist Hajime Ouchi in 1973 [Ouchi77]. The inset appears to be on a different plane from the main figure, and to vibrate.
The Scintillating Grid illusion (page 161) was discovered by Elke Lingelbach in 1994 [Schrauf97]. Black spots appear to sparkle in the white disks where the grid lines meet.
The drawing on page 96 is based on Kitaoka’s Waves illusions (2004). Gentle waves appear to undulate through the circles. The Rotating Snakes illusion (page 136) was devised by Kitaoka in 2003. If you haven’t seen the original, you owe it to yourself to visit http://www.psy.ritsumei.ac.jp/~akitaoka/rotsnakee.html. The effect is breathtaking. Both waves and rotating snakes are based on the stepwise luminance profile variant of the Peripheral Drift illusion [Kitaoka03b].
Illusions of Lightness
An illusion of lightness is an image in which we misperceive the lightness (or luminance) of some portion of the image. The simplest lightness illusion is the Simultaneous Contrast illusion, in which areas of identical lightness appear lighter or darker depending on the background against which they’re displayed. This effect has been known since ancient times. It is demonstrated by the images on pages 163 and 165. In both of these images, the central rectangle and the second frame from the outside are the same shade of gray throughout, but they appear to get lighter as the surrounding frame gets darker.
The checkerboard pattern on page 23 is based loosely on the Craik-O’Brien- Cornsweet illusion. The top and bottom squares appear lighter than the left and right squares, but all four squares are identical. The lighter corners of the top and bottom squares point inward, while the lighter corners of the left and right squares point outward. Changes in lightness at the edges where the squares meet influence your perception of the relative lightness of the squares.
Logvinenko’s illusion (page 189) was devised by vision scientist Alexander Logvinenko [Logvinenko99]. Strange as it may seem, the horizontal cube faces are all the same shade of gray. If you think the horizontal faces in the first and third rows are lighter than the ones in the second and fourth, cover the vertical faces with a mask and prepare to be surprised. The effect underlying this illusion is closely related to the Craik-O’Brien-Cornsweet illusion.
A similar effect is exploited in Todorovic’s Gradient Chessboard illusion (page 149), devised by vision scientist Dejan Todorovic [Todorovic97]. Though the disks on the checkerboard appear to be of three different shades of gray, they are all the same.
The Vasarely illusion, devised by op artist Victor Vasarely, is shown on pages 228 and 229. There appears to be a dark cross on the diagonals of the light version (page 228) and a light cross on the diagonals of the dark version (page 229), but no such crosses exist.
The drawing on page 211 is based on White’s effect [White79]. The gray bars separated by white bars appear lighter than the gray bars separated by black bars, but all the gray bars are the same.
The drawing on page 135 is based on Adelson’s Illusion of Haze [Adelson99]. The central diamond, which appears clear, is exactly the same shade of gray as the two flanking diamonds, which appear hazy.
The drawing on page 127 is based loosely on Kitaoka’s Light of Chrysanthe- mums (2005), which uses Zavagno’s Glare effect [Zavagno99]. The center of the flower appears unnaturally bright and an illusory fog appears between the petals.
Compound Illusions
Compound illusions combine two or more illusory effects. The drawing on page 160 is based on Ehrenstein’s figure, discovered by Walter Ehrenstein in 1941. It combines subjective contours with an illusion of lightness. Your mind perceives circles where the grid lines converge, and the circles are unnaturally bright.
The Subjective Necker Cube (pages 33 and 224) was devised by Bradley and Petry [Bradley77]. It combines subjective contours with an ambiguous figure. You can see two cubes, one at a time, but the figure contains none. It merely suggests the edges that comprise these cubes.
The drawing on page 57, based on the Dahlia Contours illusion by vision sci- entist Nicholas Wade, combines subjective contours with an illusion of lightness: Your mind perceives concentric circles at the radii where the arcs cross, and the circles appear brighter than the surrounding page.
Appendix B • Notes on the Illusions 263
264 Appendix B • Notes on the Illusions
The drawings on pages 48 and 49 are based on the Neon Square illusion of Marc Albert and Donald Hoffman [Albert99]. This illusion combines subjective contours with the Neon Spreading effect [van Tuijl75]. Not only do you perceive squares where none exist, but the squares have illusory color. The illusory square on page 48 appears hazy and the one on page 49 appears dark.
The drawing on page 125 uses an effect similar to the one that Kitaoka used in cushion, bulge, and checkered flag. The drawing looks like a spiral, but it consists of concentric circles. If you move towards the drawing or away from it, it appears to rotate.
The drawing on page 92 combines the “out-of-focus” effect found in Kitaoka’s Earthquake (2001) with MacKay’s squares. The frame appears to float above the defocused grid, and the grid appears to vibrate.
Finally, the front cover illustration combines the Peripheral Drift illusion, the Scintillating Grid, and a third unnamed illusion. The outer ring of fishes appears to rotate clockwise, the inner ring appears to rotate counterclockwise, the white disks at the intersections of the grid lines appear to sparkle, and the grid inset appears to move slightly relative to the fishes.
References
[Adelson99]
[Albert99]
[Boute92]
[Boxing]
[Bracha04]
Adelson, E. H. “Lightness perception and lightness illusions.” In M. S. Gazzaniga (Ed.), The New Cognitive Neurosciences, MIT Press, 2nd ed., 1999: 339–351. ISBN: 0262071959. Also available as http://web.mit.edu/persci/people/adelson/pub_pdfs/gazzan.pdf
Albert, Marc K., and Donald D. Hoffman, “The generic-viewpoint assumption and illusory contours.” In Perception, Vol. 29 (1999): 303–312.
Boute, Raymond. “The Euclidean definition of the functions div and mod.” In ACM Transactions on Programming Languages and Systems, Vol. 14, No. 2 (April 1992): 127–144.
Autoboxing. Sun Microsystems. 2004. http://java.sun.com/j2se/5.0/docs/guide/language/autoboxing.html
Bracha, Gilad. Generics in the Java Programming Language. 2004. http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
265
266 References [Bradley77]
[Bug]
[Eclipse]
[EJ]
[Features-1.4]
[Features-5.0]
[Gamma95]
[Gregory79]
[Hovemeyer04]
[IEEE-754]
[ISO-8859-1]
Bradley, D. R., and H. M. Petry. “Organizational determinants of subjective contour: the subjective Necker cube.” In American Journal of Psychology, Vol. 90 (June 1977): 253–262.
Java Bug Database. Sun Microsystems, 1994–2005. http://bugs.sun.com/bugdatabase/index.jsp
Eclipse Downloads. The Eclipse Foundation, 2002–2005. http://www.eclipse.org/downloads/index.php
Bloch, Joshua. Effective JavaTM Programming Language Guide. Addison-Wesley, 2001. ISBN: 0201310058.
J2SE 1.4.2 Summary of New Features and Enhancements.
Sun Microsystems, 2002. http://java.sun.com/j2se/1.4.2/docs/relnotes/features.html
New Features and Enhancements J2SE 5.0. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/docs/relnotes/features.html
Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides.
Design Patterns: Elements of Reusable Object-Oriented Software.
Addison-Wesley, 1995. ISBN: 0201633612.
Gregory, Richard L., and Priscilla Heard. “Border locking and the
Café Wall illusion.” In Perception, Vol. 8 (1979): 365–380. Hovemeyer,David,andWilliamPugh.FindBugs—FindBugsin
Java Programs. 2004–2005. http://findbugs.sourceforge.net
IEEE Standard for Binary Floating-Point Arithmetic. Institute of Electrical and Electronics Engineers. IEEE 754-1985 (R1990). 1990.
ISO/IEC JTC 1/SC 2/WG 3. ISO 8859, 8-bit Single-Byte Coded Graphic Character Sets—Part 1: Latin Alphabet No. 1.
ISO 8859-1:1987. 1987.
[ISO-C]
[Java-5.0]
[Java-API]
[JDK-5.0]
[Jikes]
[JLS]
[JLS2]
[JVMS]
[Kitaoka01]
[Kitaoka02]
[Kitaoka03]
References 267 Programming Languages—C. International Organization for
Standardization. ISO/IEC 9899:1999. 1999.
Java Programming Language Enhancements in JDK 5. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/docs/guide/language
Java 2 Platform Standard Edition 5.0 API Specification. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/docs/api
Download Java 2 Platform Standard Edition 5.0. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/download.jsp
Jikes Home. Open Source Technology Group, 1997–2005. http://jikes.sourceforge.net
Gosling, James, Bill Joy, Guy Steele, and Gilad Bracha.
The JavaTM Language Specification, Third Edition. Addison- Wesley, 2005. ISBN: 0321246780. Also available as http://java.sun.com/docs/books/jls/download/langspec-3.0.pdf
Gosling, James, Bill Joy, Guy Steele, and Gilad Bracha.
The JavaTM Language Specification, Second Edition.
Addison-Wesley, 2000. ISBN: 0201310082.
Lindholm, Tim, and Frank Yellin. The JavaTM Virtual Machine Specification, Second Edition. Addison-Wesley, 1999.
ISBN: 0201432943.
Kitaoka, A., B. Pinna, and G. Brelstaff. “New variations of spiral illusions.” In Perception, Vol. 30 (2001): 637–646.
Kitaoka, Akiyoshi. Trick Eyes, Kanzen, Tokyo, 2002. ISBN: 4901782118.
Kitaoka, Akiyoshi. Trick Eyes 2, Kanzen, Tokyo, 2003. ISBN: 4901782169.
268 References [Kitaoka03b]
[Kitaoka05]
[Knuth98]
[Liskov87]
[Logvinenko99]
[MaryBlog]
[Modula-3]
[Ouchi77]
[Schrauf97]
[Shepard90]
Kitaoka, Akiyoshi, and Hiroshi Ashida. “Phenomenal characteristics of the peripheral drift illusion.” In Vision (Japan), Vol. 15, No. 4 (2003): 261–262. Also available as http://www.psy.ritsumei.ac.jp/~akitaoka/PDrift.pdf
Kitaoka, Akiyoshi. Trick Eyes, Barnes and Noble Publishing, October 2005.
Knuth, Donald E. The Art of Computer Programming, Volume 2: Seminumerical Algorithms, Third Edition. Addison-Wesley, 1998. ISBN: 0201896842.
Liskov, B. “Data abstraction and hierarchy.” In Addendum to the Proceedings of OOPSLA ’87 and SIGPLAN Notices, Vol. 23, No. 5: 17–34, May 1988.
Logvinenko, Alexander D. “Lightness induction revisited.” In Perception, Vol. 28 (1999): 803–816.
Smaragdis, Mary. Weblog: MaryMaryQuiteContrary. 2004–2005. http://blogs.sun.com/roller/page/mary
Nelson, Greg (ed.). Systems Programming with Modula-3. Prentice Hall, 1991. ISBN: 0135904641.
Ouchi, Hajime. Japanese Optical and Geometrical Art. Dover Publications, 1977. ISBN: 048623553X.
Schrauf, M., B. Lingelbach, and E. R. Wist. “The scintillating grid illusion.” In Vision Research, Vol. 37 (1997): 1033–1038.
Shepard, Roger N., Mind Sights: Original Visual Illusions, Ambiguities, and Other Anomalies, with a Commentary on the Play of Mind in Perception and Art. W.H. Freeman and Co, 1990. ISBN: 0716721341.
[Spehar00]
[ThreadStop]
[Todorovic97]
[van Tuijl75]
[Turing36]
[Watanabe92]
[White79]
[Zavagno99]
Spehar, B. “Degraded illusory contour formation with non-uniform inducers in Kanizsa configurations: the role of contrast polarity.” In Vision Research, Vol. 40, No. 19 (September 2000): 2653–2659.
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated? Sun Microsystems, 1999. http://java.sun.com/j2se/5.0/docs/guide/misc/ threadPrimitiveDeprecation.html
Todorovic, D. “Lightness and junctions.” In Perception, Vol. 26 (1997): 379–394.
van Tuijl, H.F. “A new visual illusion: neonlike color spreading and complementary color induction between subjective contours.” In Acta Psychologica, Vol. 39 (1975): 441–445.
Turing, A. “On Computable Numbers, with an Application to the Entscheidungsproblem.” In Proceedings of the London Mathematical Society, Series 2, Vol. 42, 1936; reprinted in
M. David (ed.), The Undecidable, Dover Publications, 2004.
Watanabe, T., and P. Cavanagh. “Depth capture and transparency of regions bounded by illusory, chromatic, and texture contours.” In Vision Research, Vol. 32 (1992): 527–532.
White, M. “A new effect of pattern on perceived lightness.” In Perception, Vol. 8 (1979): 413–416.
Zavagno, D. “Some new luminance-gradient effects.” In Perception, Vol. 28 (1999): 835–838.
References 269
This page intentionally left blank
Index
Symbols
- unary negation operator, 14, 72, 210 - subtraction operator, 154
!= not equal to operator, 70
% remainder operator, 6, 150
%= compound assignment operator for remainder, 22, 68
%n printf end-of-line format, 37
& AND operator, 7, 91
&& conditional-AND operator, 91
&= compound assignment operator for
AND, 22, 68
*= compound assignment operator for
multiplication, 22, 68
+ addition operator, 26, 30, 66
precedence of, 31
+ string concatenation operator, 26, 28,
30, 66
++ increment operator, 56
+= compound assignment operator for
addition, 22, 68
/ division operator, 6
/* */ comment delimiters, 42 // end of line comment, 36, 43
/= compound assignment operator for division, 22, 68
< less-than relational operator, 70, 74, 237 << left shift operator, 60
<<= compound assignment operator for
left shift, 22, 68
<= less-than-or-equal relational operator, 70 <=> Perl comparison operator, 156
= assignment operator, 22, 24
-= compound assignment operator for
subtraction, 22, 68
== equal-to operator, 30, 70, 211–212
vs. equals, 29–31
> greater-than relational operator, 70, 237
>= greater-than-or-equal relational operator, 70 >> right shift operator, 60
>>= compound assignment operator for
right shift, 22, 68
>>> unsigned right shift operator, 60 >>>= compound assignment operator for
unsigned right shift, 22, 67, 68 ?: conditional operator, 19, 237
operand types and, 177–179 @Override annotation, 139
271
272 Index
\ escape character, 44, 46
\’single quote escape sequence, 32 \\ escaped backslash, 32
\n newline escape sequence, 32
\t tab escape sequence, 32
\u unicode escape sequence, 35
^ exclusive-OR operator, 18
^= compound assignment operator for
exclusive-OR, 17, 22, 68
| OR operator, 91
|= compound assignment operator for
OR, 22, 68
|| conditional-OR operator, 91
Numerics
42, 175
A
abrupt completion, 78 access modifiers
hiding fields and, 158
overriding methods and, 158, 168 accessing nonpublic types, 189–192 acronyms, naming conventions and, 164 addition operator, 30
precedence of, 31
Adelson’s Illusion of Haze, 135, 263 advanced language features,
reflection and, 197
alternate constructor invocation, 124 Ambiguous Arrows, 158, 231, 259 Ambiguous Cube, 67, 259
ambiguous figures, 33, 67, 97, 100, 101,
158, 224, 231, 259, 263 Ambiguous Letters, 97, 259 Ambihelical Hex Nut, 154, 249, 260 AND operators
bitwise, 7 conditional, 91 logical, 91
annotations, @Override, 139 annotations, Class, 216
anomalous motion illusions, 47, 96, 136
161, 173, 192, 203, 230, 262 antisymmetric relation, 70
API changes, incompatible, 174
arithmetic
decimal, 9
double, 8
floating point, 8, 62, 63, 64 IEEE 754, 62, 64
int, 10, 73
long, 10
mixed-type, 69
modular, 73
two’s complement binary, 16, 59, 72, 151
arithmetic operations, type conversions in, 68 arithmetic operators
overloading, 9, 133
performance, 7 ArrayIndexOutOfBoundsException, 90,
151
Arrays.asList, 235 Arrays.deepToString, 141–143 Arrays.equals, 142 Arrays.hashCode, 142 Arrays.sort, 154 Arrays.toString, 142, 170 assignment compatibility, 24 assignment operators
See compound assignment operator
See simple assignment operator assignment, definite, 81–83 autoboxing, 152, 169, 213
operators and, 69–71
B
backslash character, 44, 46
backward compatibility, 173–175 BigDecimal, 9 BigDecimal.signum, 143 BigInteger, 131–133 BigInteger.bitCount, 143 BigInteger.signum, 143
binary compatibility, 231
binary floating-point arithmetic, 8, 63 binary numeric promotion, 20, 21, 212 bit
masks, 17
shifts, 59–61 twiddling, 141–143
bitwise AND operator, 7
blank finals, 81–83
block comments, 41–43 blocking, 200
boxed numeric types, 70 break statements, 49–52 buffers, flushing, 197–199 bugs, tools for finding, 3, 50 Bulge illusion, 152, 261 Byte.MAX_VALUE, 54
C
Café Wall illusion, 39, 261
Calendar problems, 143–145 callback, ObjectInputValidation.
validateObject, 227 cast operator, 114
casting, 15–17, 113–114
hiding and, 159
unchecked, 95
catch clauses, rules for, 79–81 char
arrays, string representation of, 28
concatenation of, 26
character literals, escape sequences and, 33 character sets, 39–41
character vs. integer interpretation, 26 Character.reverseBytes, 143 Charset.defaultCharset, 40
checked exceptions
catch clauses and, 80
method declarations and, 41, 80 re-raising, 204
static initializers and, 81
checkerboard pattern, 23, 262 Checkered Flag illusion, 169, 261 Class.forName, return type of, 216 Class.getAnnotation, 216 Class.getName, 28 Class.newInstance, 86, 94
specification for, 196
vs. Constructor.newInstance, 95 ClassCastException, 114, 215 classes
extending inner, 221–223, 229–230 initialization cycles, 111–113
initialization of, 119–121, 205–207 deadlock during, 207
inner, generics and, 217–220 library, constants and, 231–233 member, 197
static vs. nonstatic, 219 missing, 97–100
name reuse, 161–163 naming, 148, 164
nested static, type parameters and, 220 Object.toString and, 28 precedence of members, 170 reflection and, 100
static vs. inner, 223 ClassNotFoundError, 97–100 CloneNotSupportedException, 80 Closeable.close, 88
code migration to generics, 216 Collections, 155 Collections.reverseOrder, 155 Collections.shuffle, 235 comments
delimiters, 32, 42, 43 nesting, 42
string literals in, 41–43 Unicode escapes in, 33–37
Comparator, 237–238 subtraction based, 152–156
comparison operators numerical, list of, 70 rules for operands of, 70
comparisons
mixed-type, 53–55, 74 reference vs. value, 70, 71, 146
compilers
error detection by, 3, 50 halting problem and, 82
compile-time constant expression, 232 composition, vs. inheritance, 107–109, 184 compound assignment operators, 22, 67–69
for addition, 22
avoiding type conversion in, 22–23 casting, 21–23
for exclusive OR, 17
list of, 68
operands, 23–24
Index 273
274 Index
result types of, 22
rules for operands of, 24 computations, mixed-type, 69 concatenation
operator, 26, 28, 30, 66 precedence of, 31
string, 25–27
conditional compilation, 43 conditional expressions, 19–21, 237
operand types of, 177–179
result types of, 20 conditional operators, 89–91 constant variables, 232 constants
inheriting from interfaces, 171 library classes and, 231–233 vs. magic numbers, 55, 76 naming, 164
Constructor.newInstance, 95 constructors
exception declarations by, 86 hidden, serialization and, 201–203 of inner classes, 195–197 invoking superclass, 222
of non-static nested classes, 196 order of execution in, 86 overridable methods and, 227 signatures of, 148
vs. members, 174
vs. methods, 147–148
contours
See subjective contours
conversions
See type conversions
See unboxing conversions
covariant return types, reflection and, 197 Craik-O’Brien-Cornsweet illusion, 23,
189, 262, 263 Cushion illusion, 65, 261
D
Dahlia Contours illusion, 57, 263 Date problems, 143–145
Date, name conflict with, 163 deadlock, 200, 205–207
during class initialization, 207 finalizers and, 85
decimal arithmetic, 9 decimal literals, 14 declarations
obscuring and, 170 of exceptions, 41 parameterized, 215 shadowing and, 170
default constructors, 148 definite assignment, 81–83 deprecated methods
Runtime.runFinalizersOnExit, 84 System.runFinalizersOnExit, 84 Thread.stop, 93
Thread.suspend, 93
deserialization of object graphs, 224–228 Double.NaN, 64, 212 Double.POSITIVE_INFINITY, 62 Double.toString, 8
dynamic dispatch, 180 static methods and, 110
E
eager initialization, 120–121 Ebbinghaus illusion, 137, 260 Ehrenstein illusion, 35, 261 Ehrenstein’s figure, 160, 263 Elvis, 111–113 encapsulation, 159, 173 end-of-line comment, 48 enum constants, 233
enum types, 152, 179 reflection and, 197
equality operators, 70, 71 reference, 146 value, 146
equals, vs. ==, 29–31 equivalence relation, 211 Error, 86
catching, 100
error streams, draining, 201 escape sequences, 32
in character literals, 33 HTML entity, 34
octal, 32
in string literals, 33, 44
Unicode, 31
in comments, 33–35, 35–37 compilation and, 32, 36
vs. escape sequences, 31–33, 37 obfuscation and, 37–38
in string literals, 32
Windows file names and, 34
vs. Unicode escapes, 31–33 evaluation order, 75–76 Exception
catching, 80
serialization and, 202
exception checking, bypassing, 93–96 exceptions
See also checked exceptions See also unchecked exceptions checking, 96 Class.newInstance and, 94 loop control and, 89–91 verification and, 99
exclusive OR operator, 17, 18 exponent in floating-point
representation, 72
exponential algorithms, 101–103 expression statement, 48
expressions, evaluation order of, 18, 19 extending inner classes, 221–223,
229–230
F
factorial, 234
fairness of shuffling, 233–237 fencepost errors, 49–52
fields
hiding, access modifiers and, 158
int, initial value of, 226
figure-ground illusions, 97, 158, 231, 259 File.separator, 45
final
fields, hiding and, 171–172
methods vs. fields, 172 finalizers, deadlock and, 85 finally clauses
exceptions in, 88
exiting, 78, 88
first common superclass, 99
flags for javac
-source, 177 -Xlint:fallthrough, 50
Float.NaN, 212
floating point arithmetic, 8
infinity in, 61–63
NaN, 63–64
floating-point representation, 72, 74 flow analysis, 99
flushing buffers, 197–199
for-each loop, 213
formal parameters, 106
Fraser figure, 13, 221, 260
Fringed Edges illusion, 261
G
generic interface, 214 generics, 152, 213
inner classes and, 217–220 reflection and, 197
type checking for, 95
vs. raw types, 213–216
geometrical illusions, 13, 35, 39, 65, 85, 93, 125, 137, 152, 169, 221, 225, 260–261
H
half-open loop form, 74 halting problem, 82 hashCode contract, 133–135 hashCode, identity based, 134 HashMap, 146, 148, 226
serialization and, 228
HashSet, serialization and, 228 HashSet.readObject, 226 Hashtable, serialization and, 228 hexadecimal, 14, 31, 37, 54 hexadecimal representation of int, 72 hidden constructors, 201–203
hiding, 110, 111, 157–160, 174
casting and, 159
definition of, 180
fields, access modifiers and, 158 final fields and, 171–172
vs. overloading, 109–111
HTML entity escapes, 34
Index 275
276 Index
I
identity-based hash-code, 134 IdentityHashMap, 145–146
idiom, private constructor capture, 123–124 if statement to comment out code, 43 IllegalAccessException, 86, 95 IllegalArgumentException, 94, 144 Illusion of Haze, Adelson’s, 135, 263 illusions of lightness
See lightness illusions illusory contours
See subjective contours immutability, 132
impossible figures, 36, 59, 63, 109,
122, 126, 154, 164, 200, 249, 260 Impossible Ring, 109, 164, 260 Impossible Trident, 59, 200, 260 incompatible API changes, 174 inference, of return type, 216 infinite recursion, 85–87
infinity, 61–63 inheritance
of private members, 229–230
vs. composition, 107–109, 184, 194 initialization
of classes, 119–121, 205–207 eager, 120–121
instance, 115–119
of instance variables, 85–87 lazy, 120–121
of object graph, 226 inner classes
default public constructor of, 196 extending, 221–223, 229–230 generics and, 217–220
vs. static, 223
instance
fields, updating, 220 initialization, 115–119 lock, 187
methods, qualifiers of, 110 variable initialization, 86
instanceof, 113–114 instantiation, reflection and, 191
InstantiationException, 86, 95, 196 integer division, 5–7, 9–11
integer literals
octal values of, 140
padding, 141
Integer.bitCount, 143 Integer.highestOneBit, 143 Integer.lowestOneBit, 143 Integer.MAX_VALUE, 58, 74, 209–210
subtraction-based Comparator and, 155 Integer.MIN_VALUE, 58, 72, 151, 210
Math.abs and, 149–151 Integer.numberOfLeadingZeros, 143 Integer.numberOfTrailingZeros, 143 Integer.reverse, 143 Integer.reverseBytes, 143 Integer.rotateLeft, 143 Integer.rotateRight, 143 Integer.signum, 143
integral types, boundary conditions of, 58 interfaces
for method invocation, 191
inheriting constants from, 171 interned strings, 30, 146 InterruptedException, 80, 204 InvocationTargetException, 95 IOException, 80, 88 isInterrupted, 204
ISO-8859-1, 40
J
Jastrow illusion, 85, 260
java.lang, name reuse and, 162 java.lang.reflect.Constructor, vs.
Class.newInstance, 196 java.util.concurrent.locks, 187 java.util.regex, 141–143 java.util.ThreadLocal, 124 javac, 50, 177
join points, 99
K
Kanizsa Dot Window, 69, 261 Kanizsa Triangle, 146, 242, 261
keywords final, 172 null, 126, 232 super, 159 this, 124, 223
L
languages, safe vs. unsafe, 99 Latin-1 character set, 40
lazy initialization, 120–121
least common supertype, 178
left shift operators, 59
less-than operator, 74
libraries, development of, 231–233 library classes
constants in, 231–233
locking and, 187
Light of Chrysanthemums, 127, 263 lightness illusions, 23, 48, 49, 57, 127,
135, 149, 160, 163, 165, 189, 211,
228, 229, 262, 263
line separators, 35–37
line terminators, 36 LinkedHashSet, 141–143 linking, steps in, 99
Liskov Substitution Principle, 160 List, 142
literals, 55
class, generic types and, 216 naming of, 12
string, escape sequences and, 33 string, in comments, 41–43 Unicode escapes in, 32
values of, 14
local variable declaration statements, 127–130 locking, 185–188
of instance vs. thread, 188
library classes and, 187
locks, reentrant, 187
logical operators, 89–91 Logvinenko’s illusion, 189, 263 long arithmetic, 10 Long.bitCount, 143 Long.highestOneBit, 143 Long.lowestOneBit, 143
Long.MIN_VALUE, 72 Math.abs and, 151
Long.numberOfLeadingZeros, 143 Long.numberOfTrailingZeros, 143 Long.reverse, 143 Long.reverseBytes, 143 Long.rotateLeft, 143 Long.rotateRight, 143 Long.signum, 143
loops
exceptions for control of, 89–91 types of indices for, 75
M
MacKay’s Rays, 203, 262 MacKay’s Squares, 47, 92, 192,
230, 262, 264
magic numbers, 55, 76 mantissa, in floating-point
representation, 72 Map, 146
Matcher.quoteReplacement, 46 Math.abs, 149–151 Math.signum, 143
members, 174
classes, static vs. nonstatic, 197, 219 precedence, vs. static imports, 170 private, inheritance of, 229–230
methods
exception declarations, 41
naming, 133, 148
overloading, 21, 29
overridable, constructors and, 227 overriding package-private, 167–168 overriding, access modifiers and, 158 signatures of overriding, 139 synchronized, 184
unintentional overloading of, 137–139 vs. constructors, 147–148
migrating code to generics, 216 mixed types
arithmetic on, 69
comparisons of, 53–55, 74 computations with, 13–15, 69 conditional expressions and, 20 equality operators and, 71
Index 277
278 Index
modular arithmetic, 73
monetary calculations, 7–9 multiple assignments, 19, 55–56 multiplication operator, 76 multithreading, 184
locking and, 185–188 mutual exclusion, 187
N
name reuse, 161–163, 175 naming
classes, 148, 164 conflicts, within Java, 163 constants, 164 conventions, 148, 164
acronyms and, 164 literals, 12
methods, 133, 148 packages, 164
type parameters, 164
variables, 11–12, 164
NaN, 63–64
narrowing primitive conversions, 16,
21–23, 67–69
Necker Cube, Subjective, 33, 100, 101,
224, 261, 263
Neon Spreading effect, 48, 49, 264 Neon Square illusion, 48, 49, 264 nested classes, reflection and, 197 nesting
comments, 42
try-catch constructs, 88 NoClassDefFoundError, 98 nonstatic member classes, 197, 219 NoSuchMethodError, 162 notify, 187
notifyAll, 187
null keyword, 126, 232 NullPointerException, 114, 126 numerical comparison operators, 70, 71
O
Object, name conflict with, 163 Object.clone, 118 Object.equals, 118, 134, 176
overloading, 138, 176
Object.getClass(). getMethod(methodName), 191
Object.hashCode
contract, 133–135
identity-based, 134
Object.notify, 187 Object.notifyAll, 187 Object.toString, 28, 170 Object.wait, 187 ObjectInputStream.readObject, 118,
224–228 ObjectInputStream.registerValidation,
227 ObjectInputValidation.validateObject,
227 objects
graph, deserialization of, 226
referencing during deserialization, 228 obscuring, 163–165
definition of, 182 syntactic context and, 166 workaround for, 165–167
octal
escapes, 32 literals, 14 values, 139–141
operands
of comparison operators, 70
of compound assignment operators, 23–24 of conditional expressions, 177–179
of simple assignment operators, 24
operators
See also compound assignment operator See also simple assignment operator addition, 30
arithmetic, precedence of, 31 autoboxing and, 69–71
bitwise AND, 7
cast, 114
comparison
operands of, 70
rules for, 70 concatenation, 66 conditional AND, 91 conditional OR, 91 conditional vs. logical, 91 equality, 70, 71
exclusive OR, 17, 18 instanceOf, 114 integer division, 6 left shift, 59
less than, 74
logical AND, 91
logical OR, 91
logical vs. conditional, 89–91 multiplication, 76
numerical comparison, 71
list of, 70
overloading of, 9, 27, 65–66, 133 performance of arithmetic, 7 postfix increment, 56
precedence of, 29–31, 76 question-mark colon
See conditional expressions remainder, 6, 76, 150
right shift, 60
shifts, behavior of, 60
string concatenation, 26, 28, 30 precedence of, 31
three-valued comparator, 156 truncating integer division, 6 unary negation, 14, 210 unsigned right shift, 60, 67
OR operators conditional, 91 logical, 91
order of evaluations, 75–76 Ouchi illusion, 173, 262 out-of-focus effect, 92, 264 output streams
draining, 201
flushing, 197–199 subprocesses and, 199–201
overflow, 9–11, 58, 71–73 silent, 151, 152–156 overloading, 175–176
of constructors, 106 definition of, 181 methods, 29
Object.equals, 138, 176 PrintStream.print, 21 PrintWriter.println, 28 String.valueof, 28 StringBuffer.append, 28
operators, 9, 27, 65–66, 133 resolution of, 105–107, 194 unintentional, 137–139
vs. hiding, 109–111
overridable methods, constructors and, 227
overriding, 110 definition of, 180 methods
access modifiers of, 158 constructors and, 118 method signatures, 139 Object.equals, 134 Object.hashCode, 138 Object.toString, 29 PrintStream.println, 28
methods, constructors and, 226 package-private methods and, 167–168
P
package-private methods, overriding, 167–168
packages
naming, 164
precedence of names, 164
parameterized declarations, 215 parameterized type, 214 parameters
formal, 106
implicit, in inner class constructor, 196 type, static nested classes and, 220
parentheses, 209–210, 237–238 for grouping, 76
order of evaluation and, 76 string concatenation and, 30
Pattern.quote, 44
patterns, typesafe enum, 179
Penrose Stairway, 63, 260
Penrose Triangle, 36, 126, 260 Peripheral Drift illusion, 96, 135, 262 platform dependencies
file name separators, 45
line separators, 37
Poiuyt, 59, 200, 260
postfix increment operator, 56
Index 279
280 Index
precedence
members vs. static imports, 170 of operators, 29–31, 76 variable names vs. types, 164
precision, silent loss of, 212
preorder traversal, 103
PrintStream, specification of, 198 PrintStream.print, 21, 198 PrintStream.printf, 37 PrintStream.println, 28, 37, 80, 84 PrintStream.write, 198 PrintWriter.printf, 37 PrintWriter.println, 28, 37
private constructor capture idiom, 123–124 private members, 173–175
Process, 200, 201
ProcessBuilder, 201 ProcessBuilder.redirectErrorStream,
refactoring
definite assignment and, 83 inner classes and generics, 220
reference equality, 146
reference identity comparisons, 70, 71 reflection, 189–192
advanced language features and, 197 class detection with, 100 instantiating inner classes and, 197 missing classes and, 97–100
reflexivity, 211
regular expressions, 43–45, 141–143 remainder operator, 6, 76, 150 remainders, 5–7
replacement strings, 45–47
result types
of compound assignment operators, 22
of conditional expressions, 20 Reutersvärd’s triangle of cubes, 122, 260 right shift operators, 60
unsigned, 60, 67
Rotating Snakes illusion, 136, 262 Runtime.addShutdownHook, 84 Runtime.halt, 85 Runtime.runFinalizersOnExit, 84
S
safe languages, 99
Scintillating Grid illusion, 161, 262 SecureRandom, 236 Serializable, 202
readResolve method and, 203 serialization, 201–203, 224–228
encapsulation and, 173
Set, 142
Shadow Letters, 27, 261 shadowing, 169–171, 174, 193–195
in constructors, 181 definition of, 181 generics and, 217–220
Shepard illusion, 93, 260 shift distances, 60 Short.reverseBytes, 143 shuffling, 233–237 shutdown hooks, 84
201
programming style, instance fields, 220 pseudoconstructors, 118 pseudorandom number generation,
systematic bias in, 236 punctuation, excessive, 237–238
Q
qualifiers, 110 qualifying, 111
static members, 166 static methods, 125–126 types
for method invocation, 191
for reflective access, 190 question-mark colon operator See conditional expressions
R
Random, 236
random number generation, 233–237 raw types, vs. generics, 213–216 real-time guarantee, 186
recursion, 101–103
infinite, 85–87 ReentrantLock, 187 ReentrantReadWriteLock, 187
sign extensions, 14, 15, 16, 17, 54
sign-bit, in floating-point representation, 72 significand, in floating-point
representation, 72
silent casting, 21–23, 54
silent loss of precision, 212
silent overflow, 10, 11, 57–59, 73,
151, 152–156
simple assignment operator, 22
operands of, 24
Simultaneous Contrast illusion, 163,
165, 262
singleton, 201–203
slash character, 45
-source, 177
Spiral illusion, 125, 264
SQL DECIMAL type, 9
Square Spiral, 221, 261 StackOverflowError, 86, 102 statement labels, 47–48
statements, abrupt completion of, 78 static
classes
nested, type parameters and, 220 vs. inner, 223
dispatch, 110, 181 fields, 107–109 imports, 169–171 member classes, 197
vs. nonstatic, 219 members, accessing, 166 methods
dynamic dispatch and, 110 qualification of, 110, 111 resolution of, 109–111, 125–126
nested classes
type parameters and, 220
static analysis tools, 3, 50
streams, output, flushing, 197–199 StrictMath.signum, 143
string concatenation operator, 26, 28, 30
precedence of, 31 string conversion, 28 string literals
in comments, 41–43 escape sequences in, 33, 44
Unicode escapes and, 32 String.indexOf, 41 String.replace, 46, 47 String.replaceAll, 44, 46 String.valueOf, 27, 28 StringBuffer.append, 28 strings
concatenation of, 25–27 conversion of, 27–29 interned, 30, 146
StringTokenizer, 142
subjective contours, 15, 27, 33, 48, 49,
57, 69, 100, 101, 146, 147, 160, 168,
224, 242, 261, 263–264
Subjective Necker Cube, 33, 100, 101,
224, 261, 263
Subjective Square, 15, 147, 168, 261 Subjective Triangle, 146, 242, 261 subprocesses, streams and, 199–201 subsumption, 160
super keyword, 159
superclasses
constructor invocation, 222
first common, 99
swapping variable values, 17–19
switch statement, 50
symmetric, 211
synchronization, 185–188
synchronized block, reentrant locks and, 187 synchronized methods, behavior of, 184 System.err, 198
System.exit, 84, 85
System.out, 198
System.out.flush, 199 System.out.print, 26 System.out.print(char), 198 System.out.print(String), 198 System.out.println, 80, 84, 199 System.out.write(int), 198 System.runFinalizersOnExit, 84 systematic bias, 236
T
target typing, 10, 11 this construct, 194
Index 281
282 Index
this keyword, 124, 223
Thread(Runnable), 194 Thread.interrupted, 203–205 Thread.isInterrupted, 204 Thread.join, 187 Thread.run, 184 Thread.sleep, 186 Thread.start, 184 Thread.stop, 93 Thread.suspend, 93
threads
interrupted status of, 204
state changes of, 203–205
Thread.run vs. Thread.start, 183–184
Three-Stick Clevis, 59, 200, 260 Throwable, catching, 80 throws clauses, constructor
declarations and, 85 Timer, 186
Titchener illusion, 137, 260 Todorovic’s Gradient Chessboard
illusion, 149, 263
tools, for detecting bugs, 3, 50 topology-preserving object graph
transformations, 146
toString, 28, 170
total ordering, Comparators and, 155 transitivity, 211
of Comparator, 155
traversal, preorder, 103
truncating integer division operator, 6 try clauses
checked exceptions in, 87–89 nesting, 88
System.exit and, 84
try-finally constructs, 77–78
flow of control in, 78
interaction with System.exit, 83–85 recursion in, 102
reentrant locks and, 187
static initializers and, 81
Turtles illusion, 225, 261
Twisted Cord illusion, 13, 221, 260 two’s-complement binary arithmetic, 16,
59, 151
asymmetry in, 71–73
type parameters
naming, 164, 220
static nested classes and, 220
type tokens, 216
type variable declaration, 166 types
conversions of, 15–17
See also narrowing primitive conversions See also widening primitive conversions byte to char, 17, 40
byte to int, 54
byte to String, 41
char to int, 40, 49–52
char[] to String, 29
double to String, 8
float to int, 73–75
int to float, 75
long to double, 75
long to float, 75
loss of precision in, 75
to String, 27–29, 65–66
erasure of, 95, 213–216 precedence of, 164
raw, vs. generics, 213–216
typesafe enum pattern, 179
U
ulp, 61–63
unary negation operator, 14, 72, 210 unboxing, 70, 152
unchecked casts, 95
unchecked exceptions, 78, 119 underflow, 58
Unicode characters, 21
char as, 28 Unicode escapes, 31
in comments, 33–35, 35–37 compiler and, 32, 36
vs. escape sequences, 31–33 Windows file names and, 34
unsafe languages, 99
unsigned right shift operator, 60, 67 UnsupportedEncodingException, 41
V
value comparisons, 70, 71 value equality, 146
varargs, 169, 213 variables
multiple assignments of, 19, 55–56 names, precedence of, 164 naming, 11–12, 164
swapping values, 17–19
Vasarely illusion, 228, 229, 263 verification, 99
virtual machine
exception checking and, 96 exiting, 84
W
wait, 187
Waves illusions, 96, 262
white space, ii, vi, 4, 104, 208, 270
for grouping, 76
parsing and, 36
White’s effect, 211, 263
widening primitive conversion, 10, 14,
16, 26, 51, 68
loss of precision in, 74, 211–212
Widgit, 59, 200, 260
wildcard type, 215
Windows file names, Unicode
escapes and, 34
X
-Xlint:fallthrough, 50
Z
Zavagno’s Glare effect, 127, 263 zero-extension, 16
Index 283
Try Safari Books Online FREE
Get online access to 5,000+ Books and Videos
FREE TRIAL—GET STARTED TODAY!
www.informit.com/safaritrial
Find trusted answers, fast
Only Safari lets you search across thousands of best-selling books from the top technology publishers, including Addison-Wesley Professional, Cisco Press, O’Reilly, Prentice Hall, Que, and Sams.
Master the latest tools and techniques
In addition to gaining access to an incredible inventory of technical books, Safari’s extensive collection of video tutorials lets you learn from the leading video training experts.
WAIT, THERE’S MORE!
Keep your competitive edge
With Rough Cuts, get access to the developing manuscript and be among the first to learn the newest technologies.
Stay current with emerging technologies
Short Cuts and Quick Reference Sheets are short, concise, focused content created to get you up-to-speed quickly on new and cutting-edge technologies.
Have you done the puzzles yet? If not, go to Chapter 1! Go directly to Chapter 1. Do not pass GO. Do not collect $200. If you read this chapter before doing the puzzles, it will take all the fun out of the book. Don’t say we didn’t warn you.
This chapter contains a concise taxonomy of traps and pitfalls in the Java plat- form. Each entry in the catalog is divided into three parts:
A short description of the trap or pitfall
Prescription: How to avoid the trap or reduce the risk of falling victim.
References: Pointers to additional information concerning the trap. This typically includes a reference to the puzzle that is based on the trap. Many entries also have Java Language Specification and Effective Java refer- ences [JLS, EJ].
239
240 Appendix A • Catalog of Traps and Pitfalls
1. Lexical Issues
This section concerns the lexical structure of Java programs: the tokens that make up programs and the characters that make up tokens.
1.1. The letter el looks like the digit 1 in many fonts Prescription: In long literals, always use a capital el (L), never a lowercase el (l).
Do not use a lone el (l) as a variable name. References: Puzzle 4.
1.2. Negative hex literals appear positive
Prescription: Avoid mixed-type computation; use long literals instead of int lit- erals where appropriate.
References: Puzzle 5; [JLS 3.10.1].
1.3. Octal literals look like decimal literals
Prescription: Avoid octal literals. If you must use them, comment all uses to make your intentions clear.
References: Puzzle 59; [JLS 3.10.1].
1.4. Unicode escapes for ASCII characters are confusing
Prescription: Don’t use Unicode escapes for ASCII characters. Where possible, use ASCII character directly. In string literals and character literals, prefer escape sequences to Unicode escapes.
References: Puzzles 14, 16, and 17; [JLS 3.2, 3.3].
1.5. Backslashes must be escaped, even in comments
Prescription: If you are writing a system that generates Java source code, escape backslashes in generated character literals, string literals, and comments. Win- dows filenames are a common source of trouble.
References: Puzzles 15 and 16; [JLS 3.3].
Appendix A • Catalog of Traps and Pitfalls 241 1.6. Block comments do not nest
Prescription: Use single-line comments to comment out code. References: Puzzle 19; [JLS 3.7, 14.21].
2. Integer Arithmetic
This section concerns arithmetic on the integral types: byte, char, short, int, and long.
2.1. Nonzero result of % operator has sign of left operand Prescription: If you need a nonnegative remainder, process the result of the %
operator by adding the modulus if the result is negative. References: Puzzles 1 and 64; [JLS 15.17.3].
2.2. Integer arithmetic overflows silently
Prescription: Use types that are sufficiently large to hold results, including inter- mediate results.
References: Puzzles 3, 26, 33, and 65; [JLS 4.2.2].
2.3. The sign of the difference of int values does not
reliably indicate their order
Prescription: Do not use a subtraction-based comparator unless you are sure that the difference between values will never be greater than Integer.MAX_VALUE. Note that this is a special case of Trap 2.2.
References: Puzzle 65; [EJ Item 11].
242 Appendix A • Catalog of Traps and Pitfalls
2.4. Compound assignment operators can cause silent
narrowing cast
Prescription: Don’t use compound assignment operators on variables of type byte, short, or char.
References: Puzzles 9 and 31; [JLS 15.26.2].
2.5. Integral types are asymmetric: Integer.MIN_VALUE
is its own negation, as is Long.MIN_VALUE Prescription: Program defensively. Use long instead of int if necessary.
References: Puzzles 33 and 64; [JLS 15.15.4].
2.6. Shift operators use only the low-order bits of their
right operand
Prescription: Shift by a constant amount; if you must shift by a variable amount, check that the shift distance is in range.
References: Puzzle 27; [JLS 15.19].
2.7. When converting between integral types, sign
extension is performed if the source type is signed
Prescription: Be careful when working with byte values, which are signed. To suppress sign extension, use a bit mask.
References: Puzzle 6; [JLS 5.1.2].
3. Floating-Point Arithmetic
This section concerns arithmetic on the floating-point types: float and double. 3.1. Floating-point arithmetic is inexact
Prescription: Don’t use floating-point where exact results are required; instead, use an integral type or BigDecimal.
Avoid floating-point loop indices.
Avoid using the ++ and -- operators on floating-point variables, as these operators have no effect on most floating-point values.
Avoid testing floating-point values for equality.
Prefer double to float.
References: Puzzles 2, 28, and 34; [JLS 4.2.3], [EJ Item 31], and [IEEE-754].
3.2. NaN is not equal to any floating-point value, including itself
Prescription: Avoid testing floating-point values for equality. This is not always sufficient to avoid problems, but it’s a good start.
References: Puzzle 29; [JLS 15.21.1] and [IEEE-754].
3.3. Conversions from int to float, long to float, and
long to double are lossy
Prescription: Avoid computations that mix integral and floating-point types. Pre-
fer integral arithmetic to floating-point. References: Puzzles 34 and 87; [JLS 5.1.2].
3.4. The BigDecimal(double) constructor returns the exact value of its floating-point argument
Prescription: Always use the BigDecimal(String) constructor; never use BigDecimal(double).
References: Puzzle 2.
Appendix A • Catalog of Traps and Pitfalls 243
244 Appendix A • Catalog of Traps and Pitfalls
4. Expression Evaluation
This section concerns aspects of expression evaluation that are not specific to inte- ger or floating-point arithmetic.
4.1. Mixed-type computations are confusing
Prescription: Avoid mixed-type computations.
When using the ? : operator with numeric operands, use the same numeric type
for both the second and third operands.
Prefer constant variables to inline magic numbers. References: Puzzles 5, 8, and 24.
4.2. Operands of operators are evaluated left to right
Prescription: Avoid multiple assignments to the same variable in the same expression. Especially confusing are multiple compound assignment operators in the same expression.
References: Puzzles 7, 25, and 42; [JLS 15.7] and [EJ Item 37]. 4.3. Operator precedence is not always obvious
Prescription: Use parentheses, not white space, to make precedence explicit. Replace inline constant expressions with named constant variables.
References: Puzzles 11, 35, and 95.
4.4. Operators == and != perform reference comparisons
on boxed primitive types
Prescription: To force a value comparison, assign or cast one operand to the appropriate primitive type before comparing.
References: Puzzle 32; [JLS 15.21, 5.1.8].
Appendix A • Catalog of Traps and Pitfalls 245 4.5. Constant variables are inlined where they are used
Prescription: Avoid exporting constant fields unless they represent true constants that will never change.
Use an identity method to make an expression nonconstant. References: Puzzle 93; [JLS 4.12.4, 13.1, 15.28].
4.6. Operators & and | evaluate both operands even when used on boolean values
Prescription: Avoid the & and | operators for boolean operands. Document any intentional uses.
References: Puzzle 42; [JLS 15.22.2, 15.24].
5. Flow of Control
This section concerns statements that affect flow of control, and exceptions.
5.1. Missing break in switch case causes fall-through Prescription: Don’t fall through from one nonempty case to another: Terminate
each nonempty case with a break. Document any intentional fall-throughs. References: Puzzle 23; [JLS 14.11].
5.2. It is difficult to terminate an int-indexed loop at Integer.MAX_VALUE
Prescription: To terminate an int-indexed loop at Integer.MAX_VALUE, use a long loop index or write the loop very carefully.
References: Puzzle 26.
246 Appendix A • Catalog of Traps and Pitfalls
5.3. Abrupt completion of a finally block masks
pending transfer of control
Prescription: Ensure that every finally block completes normally, barring a fatal error. Do not return from or throw an exception from a finally block.
References: Puzzles 36 and 41; [JLS 14.20.2].
5.4. Using exceptions for normal control flow leads to
bugs and poor performance
Prescription: Use exceptions only for exceptional cases, never for normal control flow.
References: Puzzle 42; [EJ Item 39].
6. ClassInitialization
This section concerns class loading and initialization.
6.1. Order of class initialization is top to bottom
Prescription: Ensure that static fields are initialized in an appropriate order. Use lazy initialization to resolve initialization cycles, which can involve one or more classes.
References: Puzzles 49 and 52; [JLS 12.4.2] and [EJ Item 48].
6.2. Timing of NoClassDefFoundError is unreliable
Prescription: Do not catch NoClassDefFoundError. Instead, use reflection and catch ClassNotFoundException.
More generally, don’t catch Error or its subclasses. References: Puzzle 44; [JLS 12.2.1].
7. Instance Creation and Destruction
This section concerns constructors, pseudoconstructors, instance initialization, and finalization.
7.1. Instance initializers execute before constructor body
Prescription: If a self-typed instance field causes recursion during construction, ensure that the recursion terminates.
References: Puzzle 40; [JLS 12.5].
7.2. Invoking an overridden method from a constructor
causes method to run before instance is initialized
Prescription: Never invoke an overridable method from a constructor. Use lazy initialization to resolve initialization cycles.
References: Puzzle 51; [EJ Items 15 and 48].
7.3. Failure to null out references can cause memory leaks
Prescription: Null out obsolete object references in long-lived objects. Failure to do so results in memory leaks, more properly known as unintended object reten- tions in garbage-collected languages, such as Java.
References: [EJ Item 5].
7.4. Failure to add a private constructor makes a class
instantiable
Prescription: If you want a class to be uninstantiable, add a private constructor. More generally, always provide at least one constructor; never depend on the
default constructor. References: [EJ Item 3].
Appendix A • Catalog of Traps and Pitfalls 247
248 Appendix A • Catalog of Traps and Pitfalls
7.5. Finalizers are unpredictable, dangerous, and slow
Prescription: Avoid finalizers. References: [EJ Item 6].
7.6. Cloned objects can share internal state
Prescription: Avoid implementing Cloneable. If you implement it, copy any internal objects that you do not want to share between the object and its clone.
References: [EJ Item 10].
8. Other Class- and Instance-Related Topics
This section concerns method invocation, method design, class design, and generic types.
8.1. There is no dynamic dispatch on static methods
Prescription: Never qualify a static method invocation with an expression; always use a type.
References: Puzzle 48; [JLS 15.12.4.4].
8.2. Inner classes are confusing
Prescription: Prefer static member classes to inner classes. References: Puzzles 80, 89, 90, and 92; [EJ Item 18].
8.3. Failure to make defensive copies destroys immutability
Prescription: Make defensive copies of input parameters and output values as required.
References: [EJ Item 24].
Appendix A • Catalog of Traps and Pitfalls 249 8.4. Implementing an interface affects the API of the
implementing class
Prescription: Do not implement an interface to gain unqualified access to its static fields.
Do not write an interface consisting solely of fields, a so-called constant interface. In release 5.0 and later releases, use static import as a replacement for the Con-
stant Interface antipattern.
References: [EJ Item 17] and [Java-5.0].
8.5. Using int constants as enum values is unsafe Prescription: Use enum types or, if you are using a release before 5.0, implement
Typesafe Enums. References: [EJ Item 21].
8.6. Mixing raw and parameterized types weakens type checking
Prescription: Eliminate “unchecked” warnings reported in your code.
Avoid using raw types in code intended for use with release 5.0 or a later release. References: Puzzle 88; [JLS 4.8].
8.7. Returning null instead of a zero-length array or collection is error prone
Prescription: Don’t return null from an array- or collection-returning method. References: [EJ Item 27].
250 Appendix A • Catalog of Traps and Pitfalls
9. Name Reuse
This section concerns the many forms of name reuse possible in Java. The overrid- ing prescription is: Avoid name reuse except for overriding. See also “A Glos- sary of Name Reuse” on page 180.
9.1. It is easy to overload when you intend to override
Prescription: Mechanically copy the declaration of each superclass method that you intend to override; better yet, let your IDE do it for you.
If you are using release 5.0 or a later release, use the @Override annotation. References: Puzzle 58.
9.2. Overload-resolution rules are not obvious
Prescription: Avoid overloading.
Provide static factories rather than multiple constructors.
If two methods in your API are both applicable to some invocation, ensure that both methods have the same behavior on the same actual arguments.
References: Puzzles 11, 46, and 74; [JLS 15.12.2] and [EJ Items 1 and 26]. 9.3. Programs that hide entities are difficult to
understand
Prescription: Avoid hiding.
References: Puzzles 66, 72, 73, and 92; [JLS 8.3, 8.4.8.2, 8.5].
9.4. Programs that shadow entities are difficult to understand
Prescription: Avoid shadowing.
Do not reuse names from java.lang.Object in public APIs. Don’t try to use static import on a name that is already defined. References: Puzzles 71, 73, 79, and 89; [JLS 6.3.1, 15.12.1].
Appendix A • Catalog of Traps and Pitfalls 251 9.5. Programs that obscure entities are difficult to
understand
Prescription: Avoid obscuring. Obey the naming conventions. References: Puzzles 68 and 69; [JLS 6.3.2, 6.5.2, 6.8] and [EJ Item 38].
9.6. A method with the same name as its class looks like a constructor
Prescription: Obey the naming conventions. References: Puzzle 63; [JLS 6.8] and [EJ Item 38].
9.7. Programs that reuse platform class names are difficult to understand
Prescription: Avoid reusing platform class names, and never reuse class names from java.lang.
References: Puzzle 67.
10. Strings
This section concerns character strings.
10.1. Arrays do not override Object.toString
Prescription: For char arrays, use String.valueOf to obtain the string repre- senting the designated sequence of characters. For other types of arrays, use Arrays.toString or, prior to release 5.0, Arrays.asList.
References: Puzzle 12; [JLS 10.7].
252 Appendix A • Catalog of Traps and Pitfalls
10.2. String.replaceAll takes a regular expression as
its first argument
Prescription: Ensure that the argument is a legal regular expression, or use String.replace instead.
References: Puzzle 20.
10.3. String.replaceAll takes a replacement string as
its second argument
Prescription: Ensure that the argument is a legal replacement string as defined in the java.util.regex specification, or use String.replace instead.
References: Puzzle 21.
10.4. Repeated string concatenation can cause poor
performance
Prescription: Avoid using the string concatenation operator in loops. References: [EJ Item 33].
10.5. Conversion of bytes to characters requires a charset
Prescription: Always select a charset when converting a byte array to a string or char array; if you don’t, the platform default charset will be used, leading to unpredictable behavior.
References: Puzzle 18.
10.6. Values of type char are silently converted to int, not
String
Prescription: To convert a char to a string, use String.valueOf(char). References: Puzzles 11 and 23; [JLS 5.1.2].
11. I/O
This section concerns the package java.io.
11.1. Stream.close can throw IOException
Prescription: Catch and, typically, ignore exceptions on close. References: Puzzle 41.
11.2. PrintStream.write(int) doesn’t flush output streams
Prescription: Avoid PrintStream.write(int). If you use it, call flush as required.
References: Puzzle 81.
11.3. Consume the output of a process, or it may hang
Prescription: Always consume the output of processes you create. References: Puzzle 82.
12. Threads
This section concerns multithreaded programming. Multithreaded programming is difficult! The overriding prescription is: Avoid low-level multithreaded pro- gramming where possible. Instead, use higher level multithreaded abstractions, such as those introduced by java.util.concurrent in release 5.0. This is an important special case of the advice in Trap 15.5.
12.1. Calling Thread.run doesn’t start a thread
Prescription: Never call Thread.run. References: Puzzle 76.
Appendix A • Catalog of Traps and Pitfalls 253
254 Appendix A • Catalog of Traps and Pitfalls
12.2. Library classes may lock or notify their instances
Prescription: Don’t use an instance lock if you extend a library class. Instead, use a separate lock object stored in a private field.
References: Puzzle 77; [EJ Item 15].
12.3. Thread.interrupted clears the interrupted status
Prescription: Don’t use Thread.interrupted unless you want to clear the inter- rupted status of the current thread. Use Thread.isInterrupted to check the sta- tus without changing it.
References: Puzzle 84.
12.4. Class initialization runs with the Class lock held
Prescription: To avoid the risk of deadlock, never wait for a background thread during class initialization.
References: Puzzle 85; [JLS 12.4.2].
12.5. Failure to synchronize when sharing mutable state
can result in failure to observe state changes
Prescription: Synchronize access to shared mutable state. References: [EJ Item 48].
12.6. Invoking alien method from within a synchronized block can cause deadlock
Prescription: Never cede control to an alien method from within a synchronized method or block.
References: [EJ Item 49].
12.7. Invoking wait outside of a while loop causes
unpredictable behavior
Prescription: Never invoke wait outside a while loop. References: [EJ Item 50].
Appendix A • Catalog of Traps and Pitfalls 255 12.8. Depending on the thread scheduler may result in
erratic and platform-dependent behavior
Prescription: To write robust, responsive, portable multithreaded programs, ensure that few threads are runnable at any given time.
References: [EJ Item 51].
13. Reflection
This section concerns Java’s core reflection APIs.
13.1. Reflection checks access to the entity and to its class
Prescription: Use reflection to instantiate classes; interfaces to access instances. References: Puzzle 78; [EJ Item 35].
13.2. Reflectively instantiating an inner class requires an extra argument
Prescription: Don’t use reflection on inner classes. Prefer static member classes to inner classes. References: Puzzle 80; [JLS 13.1] and [EJ Item 18].
13.3. Class.newInstance can throw undeclared checked exceptions
Prescription: Use java.lang.reflect.Constructor.newInstance instead of Class.newInstance if there is any possibility of the constructor throwing a checked exception.
References: Puzzle 43.
256 Appendix A • Catalog of Traps and Pitfalls
14. Serialization
This section concerns Java’s object serialization system.
14.1. Making a class serializable introduces a public pseudoconstructor
Prescription: Think twice before making a class serializable. Think twice before accepting the default readObject method. Write readObject methods defensively.
References: [EJ Items 54 and 56].
14.2. The serialized form is a part of a class’s public API
Prescription: Design serialized forms with the same care that you would design any other API.
References: [EJ Items 54 and 55].
14.3. Using the default serialized form leaks private fields
into a class’s public API
Prescription: Consider using a custom serialized form. References: [EJ Item 55].
14.4. Using the default serialized form can cause poor performance
Prescription: Consider using a custom serialized form. References: [EJ Item 55].
Appendix A • Catalog of Traps and Pitfalls 257 14.5. Maintaining instance-control invariants requires a
readResolve method
Prescription: Always write a readResolve method for singletons, handwritten
Typesafe Enums, and other instance-controlled instantiable classes. References: Puzzle 83; [EJ Items 2 and 57].
14.6. Failure to declare a serial version UID causes fragility
Prescription: Declare an explicit serial version UID in serializable classes. References: [EJ Items 54 and 55].
14.7. If readObject or readResolve invokes overridable methods, deserializing cyclic object graphs can cause corruption
Prescription: If a HashSet, HashMap, or Hashtable will be serialized, ensure that its contents do not refer back to it.
In readObject and readResolve methods, avoid invoking methods on objects currently being deserialized. If you must violate this advice, ensure that no prob- lematic cycles exist in the object graph.
References: Puzzle 91.
15. OtherLibraries
This section concern various Java platform libraries.
15.1. Overriding equals without overriding hashCode can cause erratic behavior
Prescription: When overriding equals, always override hashCode. References: Puzzle 57; [EJ Item 8].
258 Appendix A • Catalog of Traps and Pitfalls
15.2. Calendar and Date are poorly designed
Prescription: Be careful when using Calendar and Date; always consult the API documentation.
References: Puzzle 61.
15.3. Many classes are immutable, their method names
notwithstanding
Prescription: Do not be misled into thinking that immutable types are mutable. Immutable types include String, Integer, Long, Short, Byte, Character, Boolean, Float, Double, BigInteger, and BigDecimal.
References: Puzzle 56.
15.4. Some deprecated methods are toxic
Prescription: Avoid deprecated methods, such as Thread.stop, Thread.suspend, Runtime.runFinalizersOnExit, and System.runFinalizersOnExit.
References: Puzzle 39 and 43; [ThreadStop].
15.5. Using homemade solutions instead of libraries tends
to cause wasted effort, bugs, and poor performance
Prescription: Know and use the libraries. References: Puzzles 60, 62, and 94; [EJ Item 30].
B
Notes on the Illusions
This appendix contains brief descriptions of the illusions that appear throughout the book. The descriptions are grouped loosely by category. Within each category, the order is roughly chronological.
Ambiguous Figures
An ambiguous figure is a drawing that can be seen in two or more ways, though not at the same time. One kind of ambiguous figure is a two-dimensional drawing that can be seen to represent one of several different three-dimensional figures. The Ambiguous Cube (page 67) can be seen in three ways: as a large cube with a small cubic region missing from one corner, as a small cube sitting inside a corner of a larger one, and as a large cube with a small cube protruding from one corner.
Another kind of ambiguous figure is the figure-ground illusion, which is a drawing that can be seen in two ways, depending on what you perceive as the fig- ure and what you perceive as the background. The drawings on pages 158 and 231 can be seen as black arrows pointing outward against a white background, or as white arrows pointing inward against a black background. The drawing on page 97 can be seen as white letters against a black background, or as black shapes against a white background.
259
260 Appendix B • Notes on the Illusions Impossible Figures
An impossible figure is a two-dimensional perspective drawing of a figure that cannot exist in three dimensions. The arrangement of cubes on page 122 is based on an impossible figure drawn by Swedish artist Oscar Reutersvärd in 1934. This drawing is thought to be the first impossible figure ever devised. Reutersvärd devoted his career to impossible figures.
The Penrose Triangle (pages 36 and 126) is closely related to Reutersvärd’s triangle of cubes, but it was created independently by physicist Roger Penrose in 1954. The Penrose Stairway (page 63) was created in the mid 1950s by geneticist and psychiatrist Lionel Penrose, the father of Roger Penrose. The Penrose stair- way forms the basis of M. C. Escher’s famous lithograph Ascending and Descend- ing (1960).
The Three-Stick Clevis (pages 59 and 200) is also known by many other names, such as Widgit, Poiuyt, and Impossible Trident. Its origins are unknown, but it dates back at least to 1964, when D. H. Schuster wrote an article about it in the American Journal of Psychology. The clevis also graced the cover of the March 1965 issue of MAD Magazine, held aloft by a smiling Alfred E. Neuman. The Ambihelical Hex Nut (pages 154 and 249) and the Impossible Ring (pages 109 and 164) are two more impossible figures of unknown origin.
Geometrical Illusions: Size
The Jastrow illusion (page 85) was described by psychologist Joseph Jastrow in 1891. The two shaded areas are identical in size and shape, but most people per- ceive the top one to be smaller. The Ebbinghaus (or Titchener) illusion (page 137) was described by psychologist Hermann Ebbinghaus in 1897. The two central cir- cles are the same size, but most people perceive the one on the right to be smaller.
The Shepard illusion (page 93) is based on a 1990 drawing by Stanford psy- chologist Roger Shepard [Shepard90]. The two tabletops are the same size and shape, but perspective cues make them look very different. Shepard first demon- strated the effect in 1981.
Geometrical Illusions: Direction
The Twisted Cord illusion (pages 13 and 221), also known as the Fraser figure, was described by psychologist James Fraser in 1908. The letters “CAFE babe” on page 13 are set straight and true; the perceived tilt is illusory. What appears to be a
tilted “Square Spiral” on page 221 is in fact eight concentric squares, set straight and true.
The Ehrenstein illusion (page 35) was described by psychologist Walter Ehrenstein in 1925. The sides of the square are straight, but they appear to curve towards the center of the circles.
The Café Wall illusion (page 39) was first demonstrated by Fraser in 1908, and named by Richard L. Gregory and Priscilla Heard [Gregory79]. The lines of black and white tiles appear slanted but they are perfectly level. The illusion gets its name from the fact that it was found in a tile pattern on the wall of a café in Bristol, England.
The Cushion illusion (page 65) was devised by vision scientist and artist Akiyoshi Kitaoka in 1998. This drawing consists solely of rectangles and squares, set straight and true; the curvature is all in your mind. If you find this hard to believe, you can confirm it with a straightedge. The Bulge illusion (page 152) and the Checkered Flag illusion (page 169) were also devised by Kitaoka in 1998. They consist solely of squares, set straight and true; the bulging and rippling are in your mind. All three of these illusions are based on the same underlying effect.
The Turtles illusion (page 225) was devised by Kitaoka in 2002. The vertical edges appear tilted but they run straight up and down. The underlying effect, known as the illusion of Fringed Edges, was described by Kitaoka, Pinna and Brelstaff [Kitaoka01].
Subjective Contours
A subjective contour, also known as an illusory contour, is a perceived edge that does not exist. The classic example is found in the Kanizsa Triangle (pages 146 and 242), devised by Gestalt psychologist Gaetano Kanizsa in 1955. A white tri- angle appears to float above a black triangular outline, but the lines that form the white triangle don’t exist. Your mind constructs them from the contours implied by the “Pac-Man” figures. The variant on page 147 is based on a figure devised by Branka Spehar [Spehar00], and the variant on pages 15 and 168 is based on a fig- ure devised by Takeo Watanabe and Patrick Cavanagh [Watanabe92]. The three- dimensional variants on pages 100 and 101 are based loosely on the Subjective Necker Cube of Bradley and Petry, discussed later in this appendix. The Kanizsa Dot Window on page 69 is based on a figure drawn by Kanizsa in 1979.
The Shadow Letters on page 27 are also a subjective contour illusion. Your mind perceives the letters A, B, and C, when all that is present is the shadows that these letters would cast.
Appendix B • Notes on the Illusions 261
262 Appendix B • Notes on the Illusions Anomalous Motion Illusions
Anomalous motion illusions are drawings whose components appear to move. The MacKay’s Rays illusion (page 203) was described by Donald MacKay in 1957. Figure-eight patterns appear to move about the drawing as you scan over it with your eyes. The drawings on pages 47, 192, and 230 are based on the MacKay’s Squares illusion, described by MacKay in 1961. The figure appears to blink as you look at it. This illusion forms the basis of Reginald Neal’s op art prints Square of Three (1964) and Square of Two (1965).
The Ouchi illusion (page 173) was devised by artist Hajime Ouchi in 1973 [Ouchi77]. The inset appears to be on a different plane from the main figure, and to vibrate.
The Scintillating Grid illusion (page 161) was discovered by Elke Lingelbach in 1994 [Schrauf97]. Black spots appear to sparkle in the white disks where the grid lines meet.
The drawing on page 96 is based on Kitaoka’s Waves illusions (2004). Gentle waves appear to undulate through the circles. The Rotating Snakes illusion (page 136) was devised by Kitaoka in 2003. If you haven’t seen the original, you owe it to yourself to visit http://www.psy.ritsumei.ac.jp/~akitaoka/rotsnakee.html. The effect is breathtaking. Both waves and rotating snakes are based on the stepwise luminance profile variant of the Peripheral Drift illusion [Kitaoka03b].
Illusions of Lightness
An illusion of lightness is an image in which we misperceive the lightness (or luminance) of some portion of the image. The simplest lightness illusion is the Simultaneous Contrast illusion, in which areas of identical lightness appear lighter or darker depending on the background against which they’re displayed. This effect has been known since ancient times. It is demonstrated by the images on pages 163 and 165. In both of these images, the central rectangle and the second frame from the outside are the same shade of gray throughout, but they appear to get lighter as the surrounding frame gets darker.
The checkerboard pattern on page 23 is based loosely on the Craik-O’Brien- Cornsweet illusion. The top and bottom squares appear lighter than the left and right squares, but all four squares are identical. The lighter corners of the top and bottom squares point inward, while the lighter corners of the left and right squares point outward. Changes in lightness at the edges where the squares meet influence your perception of the relative lightness of the squares.
Logvinenko’s illusion (page 189) was devised by vision scientist Alexander Logvinenko [Logvinenko99]. Strange as it may seem, the horizontal cube faces are all the same shade of gray. If you think the horizontal faces in the first and third rows are lighter than the ones in the second and fourth, cover the vertical faces with a mask and prepare to be surprised. The effect underlying this illusion is closely related to the Craik-O’Brien-Cornsweet illusion.
A similar effect is exploited in Todorovic’s Gradient Chessboard illusion (page 149), devised by vision scientist Dejan Todorovic [Todorovic97]. Though the disks on the checkerboard appear to be of three different shades of gray, they are all the same.
The Vasarely illusion, devised by op artist Victor Vasarely, is shown on pages 228 and 229. There appears to be a dark cross on the diagonals of the light version (page 228) and a light cross on the diagonals of the dark version (page 229), but no such crosses exist.
The drawing on page 211 is based on White’s effect [White79]. The gray bars separated by white bars appear lighter than the gray bars separated by black bars, but all the gray bars are the same.
The drawing on page 135 is based on Adelson’s Illusion of Haze [Adelson99]. The central diamond, which appears clear, is exactly the same shade of gray as the two flanking diamonds, which appear hazy.
The drawing on page 127 is based loosely on Kitaoka’s Light of Chrysanthe- mums (2005), which uses Zavagno’s Glare effect [Zavagno99]. The center of the flower appears unnaturally bright and an illusory fog appears between the petals.
Compound Illusions
Compound illusions combine two or more illusory effects. The drawing on page 160 is based on Ehrenstein’s figure, discovered by Walter Ehrenstein in 1941. It combines subjective contours with an illusion of lightness. Your mind perceives circles where the grid lines converge, and the circles are unnaturally bright.
The Subjective Necker Cube (pages 33 and 224) was devised by Bradley and Petry [Bradley77]. It combines subjective contours with an ambiguous figure. You can see two cubes, one at a time, but the figure contains none. It merely suggests the edges that comprise these cubes.
The drawing on page 57, based on the Dahlia Contours illusion by vision sci- entist Nicholas Wade, combines subjective contours with an illusion of lightness: Your mind perceives concentric circles at the radii where the arcs cross, and the circles appear brighter than the surrounding page.
Appendix B • Notes on the Illusions 263
264 Appendix B • Notes on the Illusions
The drawings on pages 48 and 49 are based on the Neon Square illusion of Marc Albert and Donald Hoffman [Albert99]. This illusion combines subjective contours with the Neon Spreading effect [van Tuijl75]. Not only do you perceive squares where none exist, but the squares have illusory color. The illusory square on page 48 appears hazy and the one on page 49 appears dark.
The drawing on page 125 uses an effect similar to the one that Kitaoka used in cushion, bulge, and checkered flag. The drawing looks like a spiral, but it consists of concentric circles. If you move towards the drawing or away from it, it appears to rotate.
The drawing on page 92 combines the “out-of-focus” effect found in Kitaoka’s Earthquake (2001) with MacKay’s squares. The frame appears to float above the defocused grid, and the grid appears to vibrate.
Finally, the front cover illustration combines the Peripheral Drift illusion, the Scintillating Grid, and a third unnamed illusion. The outer ring of fishes appears to rotate clockwise, the inner ring appears to rotate counterclockwise, the white disks at the intersections of the grid lines appear to sparkle, and the grid inset appears to move slightly relative to the fishes.
References
[Adelson99]
[Albert99]
[Boute92]
[Boxing]
[Bracha04]
Adelson, E. H. “Lightness perception and lightness illusions.” In M. S. Gazzaniga (Ed.), The New Cognitive Neurosciences, MIT Press, 2nd ed., 1999: 339–351. ISBN: 0262071959. Also available as http://web.mit.edu/persci/people/adelson/pub_pdfs/gazzan.pdf
Albert, Marc K., and Donald D. Hoffman, “The generic-viewpoint assumption and illusory contours.” In Perception, Vol. 29 (1999): 303–312.
Boute, Raymond. “The Euclidean definition of the functions div and mod.” In ACM Transactions on Programming Languages and Systems, Vol. 14, No. 2 (April 1992): 127–144.
Autoboxing. Sun Microsystems. 2004. http://java.sun.com/j2se/5.0/docs/guide/language/autoboxing.html
Bracha, Gilad. Generics in the Java Programming Language. 2004. http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
265
266 References [Bradley77]
[Bug]
[Eclipse]
[EJ]
[Features-1.4]
[Features-5.0]
[Gamma95]
[Gregory79]
[Hovemeyer04]
[IEEE-754]
[ISO-8859-1]
Bradley, D. R., and H. M. Petry. “Organizational determinants of subjective contour: the subjective Necker cube.” In American Journal of Psychology, Vol. 90 (June 1977): 253–262.
Java Bug Database. Sun Microsystems, 1994–2005. http://bugs.sun.com/bugdatabase/index.jsp
Eclipse Downloads. The Eclipse Foundation, 2002–2005. http://www.eclipse.org/downloads/index.php
Bloch, Joshua. Effective JavaTM Programming Language Guide. Addison-Wesley, 2001. ISBN: 0201310058.
J2SE 1.4.2 Summary of New Features and Enhancements.
Sun Microsystems, 2002. http://java.sun.com/j2se/1.4.2/docs/relnotes/features.html
New Features and Enhancements J2SE 5.0. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/docs/relnotes/features.html
Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides.
Design Patterns: Elements of Reusable Object-Oriented Software.
Addison-Wesley, 1995. ISBN: 0201633612.
Gregory, Richard L., and Priscilla Heard. “Border locking and the
Café Wall illusion.” In Perception, Vol. 8 (1979): 365–380. Hovemeyer,David,andWilliamPugh.FindBugs—FindBugsin
Java Programs. 2004–2005. http://findbugs.sourceforge.net
IEEE Standard for Binary Floating-Point Arithmetic. Institute of Electrical and Electronics Engineers. IEEE 754-1985 (R1990). 1990.
ISO/IEC JTC 1/SC 2/WG 3. ISO 8859, 8-bit Single-Byte Coded Graphic Character Sets—Part 1: Latin Alphabet No. 1.
ISO 8859-1:1987. 1987.
[ISO-C]
[Java-5.0]
[Java-API]
[JDK-5.0]
[Jikes]
[JLS]
[JLS2]
[JVMS]
[Kitaoka01]
[Kitaoka02]
[Kitaoka03]
References 267 Programming Languages—C. International Organization for
Standardization. ISO/IEC 9899:1999. 1999.
Java Programming Language Enhancements in JDK 5. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/docs/guide/language
Java 2 Platform Standard Edition 5.0 API Specification. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/docs/api
Download Java 2 Platform Standard Edition 5.0. Sun Microsystems, 2004. http://java.sun.com/j2se/5.0/download.jsp
Jikes Home. Open Source Technology Group, 1997–2005. http://jikes.sourceforge.net
Gosling, James, Bill Joy, Guy Steele, and Gilad Bracha.
The JavaTM Language Specification, Third Edition. Addison- Wesley, 2005. ISBN: 0321246780. Also available as http://java.sun.com/docs/books/jls/download/langspec-3.0.pdf
Gosling, James, Bill Joy, Guy Steele, and Gilad Bracha.
The JavaTM Language Specification, Second Edition.
Addison-Wesley, 2000. ISBN: 0201310082.
Lindholm, Tim, and Frank Yellin. The JavaTM Virtual Machine Specification, Second Edition. Addison-Wesley, 1999.
ISBN: 0201432943.
Kitaoka, A., B. Pinna, and G. Brelstaff. “New variations of spiral illusions.” In Perception, Vol. 30 (2001): 637–646.
Kitaoka, Akiyoshi. Trick Eyes, Kanzen, Tokyo, 2002. ISBN: 4901782118.
Kitaoka, Akiyoshi. Trick Eyes 2, Kanzen, Tokyo, 2003. ISBN: 4901782169.
268 References [Kitaoka03b]
[Kitaoka05]
[Knuth98]
[Liskov87]
[Logvinenko99]
[MaryBlog]
[Modula-3]
[Ouchi77]
[Schrauf97]
[Shepard90]
Kitaoka, Akiyoshi, and Hiroshi Ashida. “Phenomenal characteristics of the peripheral drift illusion.” In Vision (Japan), Vol. 15, No. 4 (2003): 261–262. Also available as http://www.psy.ritsumei.ac.jp/~akitaoka/PDrift.pdf
Kitaoka, Akiyoshi. Trick Eyes, Barnes and Noble Publishing, October 2005.
Knuth, Donald E. The Art of Computer Programming, Volume 2: Seminumerical Algorithms, Third Edition. Addison-Wesley, 1998. ISBN: 0201896842.
Liskov, B. “Data abstraction and hierarchy.” In Addendum to the Proceedings of OOPSLA ’87 and SIGPLAN Notices, Vol. 23, No. 5: 17–34, May 1988.
Logvinenko, Alexander D. “Lightness induction revisited.” In Perception, Vol. 28 (1999): 803–816.
Smaragdis, Mary. Weblog: MaryMaryQuiteContrary. 2004–2005. http://blogs.sun.com/roller/page/mary
Nelson, Greg (ed.). Systems Programming with Modula-3. Prentice Hall, 1991. ISBN: 0135904641.
Ouchi, Hajime. Japanese Optical and Geometrical Art. Dover Publications, 1977. ISBN: 048623553X.
Schrauf, M., B. Lingelbach, and E. R. Wist. “The scintillating grid illusion.” In Vision Research, Vol. 37 (1997): 1033–1038.
Shepard, Roger N., Mind Sights: Original Visual Illusions, Ambiguities, and Other Anomalies, with a Commentary on the Play of Mind in Perception and Art. W.H. Freeman and Co, 1990. ISBN: 0716721341.
[Spehar00]
[ThreadStop]
[Todorovic97]
[van Tuijl75]
[Turing36]
[Watanabe92]
[White79]
[Zavagno99]
Spehar, B. “Degraded illusory contour formation with non-uniform inducers in Kanizsa configurations: the role of contrast polarity.” In Vision Research, Vol. 40, No. 19 (September 2000): 2653–2659.
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated? Sun Microsystems, 1999. http://java.sun.com/j2se/5.0/docs/guide/misc/ threadPrimitiveDeprecation.html
Todorovic, D. “Lightness and junctions.” In Perception, Vol. 26 (1997): 379–394.
van Tuijl, H.F. “A new visual illusion: neonlike color spreading and complementary color induction between subjective contours.” In Acta Psychologica, Vol. 39 (1975): 441–445.
Turing, A. “On Computable Numbers, with an Application to the Entscheidungsproblem.” In Proceedings of the London Mathematical Society, Series 2, Vol. 42, 1936; reprinted in
M. David (ed.), The Undecidable, Dover Publications, 2004.
Watanabe, T., and P. Cavanagh. “Depth capture and transparency of regions bounded by illusory, chromatic, and texture contours.” In Vision Research, Vol. 32 (1992): 527–532.
White, M. “A new effect of pattern on perceived lightness.” In Perception, Vol. 8 (1979): 413–416.
Zavagno, D. “Some new luminance-gradient effects.” In Perception, Vol. 28 (1999): 835–838.
References 269
This page intentionally left blank
Index
Symbols
- unary negation operator, 14, 72, 210 - subtraction operator, 154
!= not equal to operator, 70
% remainder operator, 6, 150
%= compound assignment operator for remainder, 22, 68
%n printf end-of-line format, 37
& AND operator, 7, 91
&& conditional-AND operator, 91
&= compound assignment operator for
AND, 22, 68
*= compound assignment operator for
multiplication, 22, 68
+ addition operator, 26, 30, 66
precedence of, 31
+ string concatenation operator, 26, 28,
30, 66
++ increment operator, 56
+= compound assignment operator for
addition, 22, 68
/ division operator, 6
/* */ comment delimiters, 42 // end of line comment, 36, 43
/= compound assignment operator for division, 22, 68
< less-than relational operator, 70, 74, 237 << left shift operator, 60
<<= compound assignment operator for
left shift, 22, 68
<= less-than-or-equal relational operator, 70 <=> Perl comparison operator, 156
= assignment operator, 22, 24
-= compound assignment operator for
subtraction, 22, 68
== equal-to operator, 30, 70, 211–212
vs. equals, 29–31
> greater-than relational operator, 70, 237
>= greater-than-or-equal relational operator, 70 >> right shift operator, 60
>>= compound assignment operator for
right shift, 22, 68
>>> unsigned right shift operator, 60 >>>= compound assignment operator for
unsigned right shift, 22, 67, 68 ?: conditional operator, 19, 237
operand types and, 177–179 @Override annotation, 139
271
272 Index
\ escape character, 44, 46
\’single quote escape sequence, 32 \\ escaped backslash, 32
\n newline escape sequence, 32
\t tab escape sequence, 32
\u unicode escape sequence, 35
^ exclusive-OR operator, 18
^= compound assignment operator for
exclusive-OR, 17, 22, 68
| OR operator, 91
|= compound assignment operator for
OR, 22, 68
|| conditional-OR operator, 91
Numerics
42, 175
A
abrupt completion, 78 access modifiers
hiding fields and, 158
overriding methods and, 158, 168 accessing nonpublic types, 189–192 acronyms, naming conventions and, 164 addition operator, 30
precedence of, 31
Adelson’s Illusion of Haze, 135, 263 advanced language features,
reflection and, 197
alternate constructor invocation, 124 Ambiguous Arrows, 158, 231, 259 Ambiguous Cube, 67, 259
ambiguous figures, 33, 67, 97, 100, 101,
158, 224, 231, 259, 263 Ambiguous Letters, 97, 259 Ambihelical Hex Nut, 154, 249, 260 AND operators
bitwise, 7 conditional, 91 logical, 91
annotations, @Override, 139 annotations, Class, 216
anomalous motion illusions, 47, 96, 136
161, 173, 192, 203, 230, 262 antisymmetric relation, 70
API changes, incompatible, 174
arithmetic
decimal, 9
double, 8
floating point, 8, 62, 63, 64 IEEE 754, 62, 64
int, 10, 73
long, 10
mixed-type, 69
modular, 73
two’s complement binary, 16, 59, 72, 151
arithmetic operations, type conversions in, 68 arithmetic operators
overloading, 9, 133
performance, 7 ArrayIndexOutOfBoundsException, 90,
151
Arrays.asList, 235 Arrays.deepToString, 141–143 Arrays.equals, 142 Arrays.hashCode, 142 Arrays.sort, 154 Arrays.toString, 142, 170 assignment compatibility, 24 assignment operators
See compound assignment operator
See simple assignment operator assignment, definite, 81–83 autoboxing, 152, 169, 213
operators and, 69–71
B
backslash character, 44, 46
backward compatibility, 173–175 BigDecimal, 9 BigDecimal.signum, 143 BigInteger, 131–133 BigInteger.bitCount, 143 BigInteger.signum, 143
binary compatibility, 231
binary floating-point arithmetic, 8, 63 binary numeric promotion, 20, 21, 212 bit
masks, 17
shifts, 59–61 twiddling, 141–143
bitwise AND operator, 7
blank finals, 81–83
block comments, 41–43 blocking, 200
boxed numeric types, 70 break statements, 49–52 buffers, flushing, 197–199 bugs, tools for finding, 3, 50 Bulge illusion, 152, 261 Byte.MAX_VALUE, 54
C
Café Wall illusion, 39, 261
Calendar problems, 143–145 callback, ObjectInputValidation.
validateObject, 227 cast operator, 114
casting, 15–17, 113–114
hiding and, 159
unchecked, 95
catch clauses, rules for, 79–81 char
arrays, string representation of, 28
concatenation of, 26
character literals, escape sequences and, 33 character sets, 39–41
character vs. integer interpretation, 26 Character.reverseBytes, 143 Charset.defaultCharset, 40
checked exceptions
catch clauses and, 80
method declarations and, 41, 80 re-raising, 204
static initializers and, 81
checkerboard pattern, 23, 262 Checkered Flag illusion, 169, 261 Class.forName, return type of, 216 Class.getAnnotation, 216 Class.getName, 28 Class.newInstance, 86, 94
specification for, 196
vs. Constructor.newInstance, 95 ClassCastException, 114, 215 classes
extending inner, 221–223, 229–230 initialization cycles, 111–113
initialization of, 119–121, 205–207 deadlock during, 207
inner, generics and, 217–220 library, constants and, 231–233 member, 197
static vs. nonstatic, 219 missing, 97–100
name reuse, 161–163 naming, 148, 164
nested static, type parameters and, 220 Object.toString and, 28 precedence of members, 170 reflection and, 100
static vs. inner, 223 ClassNotFoundError, 97–100 CloneNotSupportedException, 80 Closeable.close, 88
code migration to generics, 216 Collections, 155 Collections.reverseOrder, 155 Collections.shuffle, 235 comments
delimiters, 32, 42, 43 nesting, 42
string literals in, 41–43 Unicode escapes in, 33–37
Comparator, 237–238 subtraction based, 152–156
comparison operators numerical, list of, 70 rules for operands of, 70
comparisons
mixed-type, 53–55, 74 reference vs. value, 70, 71, 146
compilers
error detection by, 3, 50 halting problem and, 82
compile-time constant expression, 232 composition, vs. inheritance, 107–109, 184 compound assignment operators, 22, 67–69
for addition, 22
avoiding type conversion in, 22–23 casting, 21–23
for exclusive OR, 17
list of, 68
operands, 23–24
Index 273
274 Index
result types of, 22
rules for operands of, 24 computations, mixed-type, 69 concatenation
operator, 26, 28, 30, 66 precedence of, 31
string, 25–27
conditional compilation, 43 conditional expressions, 19–21, 237
operand types of, 177–179
result types of, 20 conditional operators, 89–91 constant variables, 232 constants
inheriting from interfaces, 171 library classes and, 231–233 vs. magic numbers, 55, 76 naming, 164
Constructor.newInstance, 95 constructors
exception declarations by, 86 hidden, serialization and, 201–203 of inner classes, 195–197 invoking superclass, 222
of non-static nested classes, 196 order of execution in, 86 overridable methods and, 227 signatures of, 148
vs. members, 174
vs. methods, 147–148
contours
See subjective contours
conversions
See type conversions
See unboxing conversions
covariant return types, reflection and, 197 Craik-O’Brien-Cornsweet illusion, 23,
189, 262, 263 Cushion illusion, 65, 261
D
Dahlia Contours illusion, 57, 263 Date problems, 143–145
Date, name conflict with, 163 deadlock, 200, 205–207
during class initialization, 207 finalizers and, 85
decimal arithmetic, 9 decimal literals, 14 declarations
obscuring and, 170 of exceptions, 41 parameterized, 215 shadowing and, 170
default constructors, 148 definite assignment, 81–83 deprecated methods
Runtime.runFinalizersOnExit, 84 System.runFinalizersOnExit, 84 Thread.stop, 93
Thread.suspend, 93
deserialization of object graphs, 224–228 Double.NaN, 64, 212 Double.POSITIVE_INFINITY, 62 Double.toString, 8
dynamic dispatch, 180 static methods and, 110
E
eager initialization, 120–121 Ebbinghaus illusion, 137, 260 Ehrenstein illusion, 35, 261 Ehrenstein’s figure, 160, 263 Elvis, 111–113 encapsulation, 159, 173 end-of-line comment, 48 enum constants, 233
enum types, 152, 179 reflection and, 197
equality operators, 70, 71 reference, 146 value, 146
equals, vs. ==, 29–31 equivalence relation, 211 Error, 86
catching, 100
error streams, draining, 201 escape sequences, 32
in character literals, 33 HTML entity, 34
octal, 32
in string literals, 33, 44
Unicode, 31
in comments, 33–35, 35–37 compilation and, 32, 36
vs. escape sequences, 31–33, 37 obfuscation and, 37–38
in string literals, 32
Windows file names and, 34
vs. Unicode escapes, 31–33 evaluation order, 75–76 Exception
catching, 80
serialization and, 202
exception checking, bypassing, 93–96 exceptions
See also checked exceptions See also unchecked exceptions checking, 96 Class.newInstance and, 94 loop control and, 89–91 verification and, 99
exclusive OR operator, 17, 18 exponent in floating-point
representation, 72
exponential algorithms, 101–103 expression statement, 48
expressions, evaluation order of, 18, 19 extending inner classes, 221–223,
229–230
F
factorial, 234
fairness of shuffling, 233–237 fencepost errors, 49–52
fields
hiding, access modifiers and, 158
int, initial value of, 226
figure-ground illusions, 97, 158, 231, 259 File.separator, 45
final
fields, hiding and, 171–172
methods vs. fields, 172 finalizers, deadlock and, 85 finally clauses
exceptions in, 88
exiting, 78, 88
first common superclass, 99
flags for javac
-source, 177 -Xlint:fallthrough, 50
Float.NaN, 212
floating point arithmetic, 8
infinity in, 61–63
NaN, 63–64
floating-point representation, 72, 74 flow analysis, 99
flushing buffers, 197–199
for-each loop, 213
formal parameters, 106
Fraser figure, 13, 221, 260
Fringed Edges illusion, 261
G
generic interface, 214 generics, 152, 213
inner classes and, 217–220 reflection and, 197
type checking for, 95
vs. raw types, 213–216
geometrical illusions, 13, 35, 39, 65, 85, 93, 125, 137, 152, 169, 221, 225, 260–261
H
half-open loop form, 74 halting problem, 82 hashCode contract, 133–135 hashCode, identity based, 134 HashMap, 146, 148, 226
serialization and, 228
HashSet, serialization and, 228 HashSet.readObject, 226 Hashtable, serialization and, 228 hexadecimal, 14, 31, 37, 54 hexadecimal representation of int, 72 hidden constructors, 201–203
hiding, 110, 111, 157–160, 174
casting and, 159
definition of, 180
fields, access modifiers and, 158 final fields and, 171–172
vs. overloading, 109–111
HTML entity escapes, 34
Index 275
276 Index
I
identity-based hash-code, 134 IdentityHashMap, 145–146
idiom, private constructor capture, 123–124 if statement to comment out code, 43 IllegalAccessException, 86, 95 IllegalArgumentException, 94, 144 Illusion of Haze, Adelson’s, 135, 263 illusions of lightness
See lightness illusions illusory contours
See subjective contours immutability, 132
impossible figures, 36, 59, 63, 109,
122, 126, 154, 164, 200, 249, 260 Impossible Ring, 109, 164, 260 Impossible Trident, 59, 200, 260 incompatible API changes, 174 inference, of return type, 216 infinite recursion, 85–87
infinity, 61–63 inheritance
of private members, 229–230
vs. composition, 107–109, 184, 194 initialization
of classes, 119–121, 205–207 eager, 120–121
instance, 115–119
of instance variables, 85–87 lazy, 120–121
of object graph, 226 inner classes
default public constructor of, 196 extending, 221–223, 229–230 generics and, 217–220
vs. static, 223
instance
fields, updating, 220 initialization, 115–119 lock, 187
methods, qualifiers of, 110 variable initialization, 86
instanceof, 113–114 instantiation, reflection and, 191
InstantiationException, 86, 95, 196 integer division, 5–7, 9–11
integer literals
octal values of, 140
padding, 141
Integer.bitCount, 143 Integer.highestOneBit, 143 Integer.lowestOneBit, 143 Integer.MAX_VALUE, 58, 74, 209–210
subtraction-based Comparator and, 155 Integer.MIN_VALUE, 58, 72, 151, 210
Math.abs and, 149–151 Integer.numberOfLeadingZeros, 143 Integer.numberOfTrailingZeros, 143 Integer.reverse, 143 Integer.reverseBytes, 143 Integer.rotateLeft, 143 Integer.rotateRight, 143 Integer.signum, 143
integral types, boundary conditions of, 58 interfaces
for method invocation, 191
inheriting constants from, 171 interned strings, 30, 146 InterruptedException, 80, 204 InvocationTargetException, 95 IOException, 80, 88 isInterrupted, 204
ISO-8859-1, 40
J
Jastrow illusion, 85, 260
java.lang, name reuse and, 162 java.lang.reflect.Constructor, vs.
Class.newInstance, 196 java.util.concurrent.locks, 187 java.util.regex, 141–143 java.util.ThreadLocal, 124 javac, 50, 177
join points, 99
K
Kanizsa Dot Window, 69, 261 Kanizsa Triangle, 146, 242, 261
keywords final, 172 null, 126, 232 super, 159 this, 124, 223
L
languages, safe vs. unsafe, 99 Latin-1 character set, 40
lazy initialization, 120–121
least common supertype, 178
left shift operators, 59
less-than operator, 74
libraries, development of, 231–233 library classes
constants in, 231–233
locking and, 187
Light of Chrysanthemums, 127, 263 lightness illusions, 23, 48, 49, 57, 127,
135, 149, 160, 163, 165, 189, 211,
228, 229, 262, 263
line separators, 35–37
line terminators, 36 LinkedHashSet, 141–143 linking, steps in, 99
Liskov Substitution Principle, 160 List, 142
literals, 55
class, generic types and, 216 naming of, 12
string, escape sequences and, 33 string, in comments, 41–43 Unicode escapes in, 32
values of, 14
local variable declaration statements, 127–130 locking, 185–188
of instance vs. thread, 188
library classes and, 187
locks, reentrant, 187
logical operators, 89–91 Logvinenko’s illusion, 189, 263 long arithmetic, 10 Long.bitCount, 143 Long.highestOneBit, 143 Long.lowestOneBit, 143
Long.MIN_VALUE, 72 Math.abs and, 151
Long.numberOfLeadingZeros, 143 Long.numberOfTrailingZeros, 143 Long.reverse, 143 Long.reverseBytes, 143 Long.rotateLeft, 143 Long.rotateRight, 143 Long.signum, 143
loops
exceptions for control of, 89–91 types of indices for, 75
M
MacKay’s Rays, 203, 262 MacKay’s Squares, 47, 92, 192,
230, 262, 264
magic numbers, 55, 76 mantissa, in floating-point
representation, 72 Map, 146
Matcher.quoteReplacement, 46 Math.abs, 149–151 Math.signum, 143
members, 174
classes, static vs. nonstatic, 197, 219 precedence, vs. static imports, 170 private, inheritance of, 229–230
methods
exception declarations, 41
naming, 133, 148
overloading, 21, 29
overridable, constructors and, 227 overriding package-private, 167–168 overriding, access modifiers and, 158 signatures of overriding, 139 synchronized, 184
unintentional overloading of, 137–139 vs. constructors, 147–148
migrating code to generics, 216 mixed types
arithmetic on, 69
comparisons of, 53–55, 74 computations with, 13–15, 69 conditional expressions and, 20 equality operators and, 71
Index 277
278 Index
modular arithmetic, 73
monetary calculations, 7–9 multiple assignments, 19, 55–56 multiplication operator, 76 multithreading, 184
locking and, 185–188 mutual exclusion, 187
N
name reuse, 161–163, 175 naming
classes, 148, 164 conflicts, within Java, 163 constants, 164 conventions, 148, 164
acronyms and, 164 literals, 12
methods, 133, 148 packages, 164
type parameters, 164
variables, 11–12, 164
NaN, 63–64
narrowing primitive conversions, 16,
21–23, 67–69
Necker Cube, Subjective, 33, 100, 101,
224, 261, 263
Neon Spreading effect, 48, 49, 264 Neon Square illusion, 48, 49, 264 nested classes, reflection and, 197 nesting
comments, 42
try-catch constructs, 88 NoClassDefFoundError, 98 nonstatic member classes, 197, 219 NoSuchMethodError, 162 notify, 187
notifyAll, 187
null keyword, 126, 232 NullPointerException, 114, 126 numerical comparison operators, 70, 71
O
Object, name conflict with, 163 Object.clone, 118 Object.equals, 118, 134, 176
overloading, 138, 176
Object.getClass(). getMethod(methodName), 191
Object.hashCode
contract, 133–135
identity-based, 134
Object.notify, 187 Object.notifyAll, 187 Object.toString, 28, 170 Object.wait, 187 ObjectInputStream.readObject, 118,
224–228 ObjectInputStream.registerValidation,
227 ObjectInputValidation.validateObject,
227 objects
graph, deserialization of, 226
referencing during deserialization, 228 obscuring, 163–165
definition of, 182 syntactic context and, 166 workaround for, 165–167
octal
escapes, 32 literals, 14 values, 139–141
operands
of comparison operators, 70
of compound assignment operators, 23–24 of conditional expressions, 177–179
of simple assignment operators, 24
operators
See also compound assignment operator See also simple assignment operator addition, 30
arithmetic, precedence of, 31 autoboxing and, 69–71
bitwise AND, 7
cast, 114
comparison
operands of, 70
rules for, 70 concatenation, 66 conditional AND, 91 conditional OR, 91 conditional vs. logical, 91 equality, 70, 71
exclusive OR, 17, 18 instanceOf, 114 integer division, 6 left shift, 59
less than, 74
logical AND, 91
logical OR, 91
logical vs. conditional, 89–91 multiplication, 76
numerical comparison, 71
list of, 70
overloading of, 9, 27, 65–66, 133 performance of arithmetic, 7 postfix increment, 56
precedence of, 29–31, 76 question-mark colon
See conditional expressions remainder, 6, 76, 150
right shift, 60
shifts, behavior of, 60
string concatenation, 26, 28, 30 precedence of, 31
three-valued comparator, 156 truncating integer division, 6 unary negation, 14, 210 unsigned right shift, 60, 67
OR operators conditional, 91 logical, 91
order of evaluations, 75–76 Ouchi illusion, 173, 262 out-of-focus effect, 92, 264 output streams
draining, 201
flushing, 197–199 subprocesses and, 199–201
overflow, 9–11, 58, 71–73 silent, 151, 152–156 overloading, 175–176
of constructors, 106 definition of, 181 methods, 29
Object.equals, 138, 176 PrintStream.print, 21 PrintWriter.println, 28 String.valueof, 28 StringBuffer.append, 28
operators, 9, 27, 65–66, 133 resolution of, 105–107, 194 unintentional, 137–139
vs. hiding, 109–111
overridable methods, constructors and, 227
overriding, 110 definition of, 180 methods
access modifiers of, 158 constructors and, 118 method signatures, 139 Object.equals, 134 Object.hashCode, 138 Object.toString, 29 PrintStream.println, 28
methods, constructors and, 226 package-private methods and, 167–168
P
package-private methods, overriding, 167–168
packages
naming, 164
precedence of names, 164
parameterized declarations, 215 parameterized type, 214 parameters
formal, 106
implicit, in inner class constructor, 196 type, static nested classes and, 220
parentheses, 209–210, 237–238 for grouping, 76
order of evaluation and, 76 string concatenation and, 30
Pattern.quote, 44
patterns, typesafe enum, 179
Penrose Stairway, 63, 260
Penrose Triangle, 36, 126, 260 Peripheral Drift illusion, 96, 135, 262 platform dependencies
file name separators, 45
line separators, 37
Poiuyt, 59, 200, 260
postfix increment operator, 56
Index 279
280 Index
precedence
members vs. static imports, 170 of operators, 29–31, 76 variable names vs. types, 164
precision, silent loss of, 212
preorder traversal, 103
PrintStream, specification of, 198 PrintStream.print, 21, 198 PrintStream.printf, 37 PrintStream.println, 28, 37, 80, 84 PrintStream.write, 198 PrintWriter.printf, 37 PrintWriter.println, 28, 37
private constructor capture idiom, 123–124 private members, 173–175
Process, 200, 201
ProcessBuilder, 201 ProcessBuilder.redirectErrorStream,
refactoring
definite assignment and, 83 inner classes and generics, 220
reference equality, 146
reference identity comparisons, 70, 71 reflection, 189–192
advanced language features and, 197 class detection with, 100 instantiating inner classes and, 197 missing classes and, 97–100
reflexivity, 211
regular expressions, 43–45, 141–143 remainder operator, 6, 76, 150 remainders, 5–7
replacement strings, 45–47
result types
of compound assignment operators, 22
of conditional expressions, 20 Reutersvärd’s triangle of cubes, 122, 260 right shift operators, 60
unsigned, 60, 67
Rotating Snakes illusion, 136, 262 Runtime.addShutdownHook, 84 Runtime.halt, 85 Runtime.runFinalizersOnExit, 84
S
safe languages, 99
Scintillating Grid illusion, 161, 262 SecureRandom, 236 Serializable, 202
readResolve method and, 203 serialization, 201–203, 224–228
encapsulation and, 173
Set, 142
Shadow Letters, 27, 261 shadowing, 169–171, 174, 193–195
in constructors, 181 definition of, 181 generics and, 217–220
Shepard illusion, 93, 260 shift distances, 60 Short.reverseBytes, 143 shuffling, 233–237 shutdown hooks, 84
201
programming style, instance fields, 220 pseudoconstructors, 118 pseudorandom number generation,
systematic bias in, 236 punctuation, excessive, 237–238
Q
qualifiers, 110 qualifying, 111
static members, 166 static methods, 125–126 types
for method invocation, 191
for reflective access, 190 question-mark colon operator See conditional expressions
R
Random, 236
random number generation, 233–237 raw types, vs. generics, 213–216 real-time guarantee, 186
recursion, 101–103
infinite, 85–87 ReentrantLock, 187 ReentrantReadWriteLock, 187
sign extensions, 14, 15, 16, 17, 54
sign-bit, in floating-point representation, 72 significand, in floating-point
representation, 72
silent casting, 21–23, 54
silent loss of precision, 212
silent overflow, 10, 11, 57–59, 73,
151, 152–156
simple assignment operator, 22
operands of, 24
Simultaneous Contrast illusion, 163,
165, 262
singleton, 201–203
slash character, 45
-source, 177
Spiral illusion, 125, 264
SQL DECIMAL type, 9
Square Spiral, 221, 261 StackOverflowError, 86, 102 statement labels, 47–48
statements, abrupt completion of, 78 static
classes
nested, type parameters and, 220 vs. inner, 223
dispatch, 110, 181 fields, 107–109 imports, 169–171 member classes, 197
vs. nonstatic, 219 members, accessing, 166 methods
dynamic dispatch and, 110 qualification of, 110, 111 resolution of, 109–111, 125–126
nested classes
type parameters and, 220
static analysis tools, 3, 50
streams, output, flushing, 197–199 StrictMath.signum, 143
string concatenation operator, 26, 28, 30
precedence of, 31 string conversion, 28 string literals
in comments, 41–43 escape sequences in, 33, 44
Unicode escapes and, 32 String.indexOf, 41 String.replace, 46, 47 String.replaceAll, 44, 46 String.valueOf, 27, 28 StringBuffer.append, 28 strings
concatenation of, 25–27 conversion of, 27–29 interned, 30, 146
StringTokenizer, 142
subjective contours, 15, 27, 33, 48, 49,
57, 69, 100, 101, 146, 147, 160, 168,
224, 242, 261, 263–264
Subjective Necker Cube, 33, 100, 101,
224, 261, 263
Subjective Square, 15, 147, 168, 261 Subjective Triangle, 146, 242, 261 subprocesses, streams and, 199–201 subsumption, 160
super keyword, 159
superclasses
constructor invocation, 222
first common, 99
swapping variable values, 17–19
switch statement, 50
symmetric, 211
synchronization, 185–188
synchronized block, reentrant locks and, 187 synchronized methods, behavior of, 184 System.err, 198
System.exit, 84, 85
System.out, 198
System.out.flush, 199 System.out.print, 26 System.out.print(char), 198 System.out.print(String), 198 System.out.println, 80, 84, 199 System.out.write(int), 198 System.runFinalizersOnExit, 84 systematic bias, 236
T
target typing, 10, 11 this construct, 194
Index 281
282 Index
this keyword, 124, 223
Thread(Runnable), 194 Thread.interrupted, 203–205 Thread.isInterrupted, 204 Thread.join, 187 Thread.run, 184 Thread.sleep, 186 Thread.start, 184 Thread.stop, 93 Thread.suspend, 93
threads
interrupted status of, 204
state changes of, 203–205
Thread.run vs. Thread.start, 183–184
Three-Stick Clevis, 59, 200, 260 Throwable, catching, 80 throws clauses, constructor
declarations and, 85 Timer, 186
Titchener illusion, 137, 260 Todorovic’s Gradient Chessboard
illusion, 149, 263
tools, for detecting bugs, 3, 50 topology-preserving object graph
transformations, 146
toString, 28, 170
total ordering, Comparators and, 155 transitivity, 211
of Comparator, 155
traversal, preorder, 103
truncating integer division operator, 6 try clauses
checked exceptions in, 87–89 nesting, 88
System.exit and, 84
try-finally constructs, 77–78
flow of control in, 78
interaction with System.exit, 83–85 recursion in, 102
reentrant locks and, 187
static initializers and, 81
Turtles illusion, 225, 261
Twisted Cord illusion, 13, 221, 260 two’s-complement binary arithmetic, 16,
59, 151
asymmetry in, 71–73
type parameters
naming, 164, 220
static nested classes and, 220
type tokens, 216
type variable declaration, 166 types
conversions of, 15–17
See also narrowing primitive conversions See also widening primitive conversions byte to char, 17, 40
byte to int, 54
byte to String, 41
char to int, 40, 49–52
char[] to String, 29
double to String, 8
float to int, 73–75
int to float, 75
long to double, 75
long to float, 75
loss of precision in, 75
to String, 27–29, 65–66
erasure of, 95, 213–216 precedence of, 164
raw, vs. generics, 213–216
typesafe enum pattern, 179
U
ulp, 61–63
unary negation operator, 14, 72, 210 unboxing, 70, 152
unchecked casts, 95
unchecked exceptions, 78, 119 underflow, 58
Unicode characters, 21
char as, 28 Unicode escapes, 31
in comments, 33–35, 35–37 compiler and, 32, 36
vs. escape sequences, 31–33 Windows file names and, 34
unsafe languages, 99
unsigned right shift operator, 60, 67 UnsupportedEncodingException, 41
V
value comparisons, 70, 71 value equality, 146
varargs, 169, 213 variables
multiple assignments of, 19, 55–56 names, precedence of, 164 naming, 11–12, 164
swapping values, 17–19
Vasarely illusion, 228, 229, 263 verification, 99
virtual machine
exception checking and, 96 exiting, 84
W
wait, 187
Waves illusions, 96, 262
white space, ii, vi, 4, 104, 208, 270
for grouping, 76
parsing and, 36
White’s effect, 211, 263
widening primitive conversion, 10, 14,
16, 26, 51, 68
loss of precision in, 74, 211–212
Widgit, 59, 200, 260
wildcard type, 215
Windows file names, Unicode
escapes and, 34
X
-Xlint:fallthrough, 50
Z
Zavagno’s Glare effect, 127, 263 zero-extension, 16
Index 283
Try Safari Books Online FREE
Get online access to 5,000+ Books and Videos
FREE TRIAL—GET STARTED TODAY!
www.informit.com/safaritrial
Find trusted answers, fast
Only Safari lets you search across thousands of best-selling books from the top technology publishers, including Addison-Wesley Professional, Cisco Press, O’Reilly, Prentice Hall, Que, and Sams.
Master the latest tools and techniques
In addition to gaining access to an incredible inventory of technical books, Safari’s extensive collection of video tutorials lets you learn from the leading video training experts.
WAIT, THERE’S MORE!
Keep your competitive edge
With Rough Cuts, get access to the developing manuscript and be among the first to learn the newest technologies.
Stay current with emerging technologies
Short Cuts and Quick Reference Sheets are short, concise, focused content created to get you up-to-speed quickly on new and cutting-edge technologies.
Comments
Post a Comment