Java Puzzle

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.

Comments