Java Puzzlers

Think you know everything there is to know about Java? Well, here's your chance to prove it. Java personalities and experts Click and Hack Type-It present a pack of precocious Java puzzlers for your education and entertainment.


Josh: Hi. We’re Click and Hack, the Type-it Brothers. Welcome to Code Talk. In today’s special edition of Code Talk, we have a series of Java programming language puzzlers to amuse and abuse you. The problems cover the language and its core libraries, specifically java.lang and java.util. In the first half of the program, we’ll give the problems, and in the second half, the solutions. We suggest you check the answer to each problem before moving on to the next one. And remember, it’s not all fun and games. Each problem also teaches some lesson, and we’ll discuss those with the solutions.

Neal: And for the competitive masochists out there who want to keep score, give yourself one point for each problem you get right, and we’ll grade you in the third half of the program.

Puzzlers One and Two: “Loopers”

Josh: To begin, we’re going to talk about loops.

Neal: What, Froot Loops?

Josh: No you dingbat, while loops! What does this loop do?

while (i == i + 1);

Neal: It’s obvious. That loop does nothing. A number is never equal to itself plus one.

Josh: Well, maybe yes, maybe no… What if that line of code is preceded by this:

double i = 1.0 / 0.0;

Believe it or not, 1.0/0.0 is legal. Java uses IEEE 754 arithmetic, which lets you store infinity in a double or float. And as we learned in grade school, infinity plus one is still infinity. So, the loop condition evaluates to true and the loop never terminates! In fact, you don’t even need to store infinity in i to make the loop spin forever. Any sufficiently large value will do. For example:

double i = 1.0e40;

Neal: Oh, I see, the larger a floating point number, the larger the distance between the number and its successor. Adding one to a floating point number this large doesn’t “bridge the gap” to its successor.

Josh: Yep. Here’s another one. What does this loop do?

while (i != i);

Neal: It has to do nothing, right?

Josh: Well, no… Suppose it’s preceded by this declaration:

double i = 0.0 / 0.0;

This strange looking expression evaluates to Double.NaN, which is short for “not a number.” It turns out that, according to the IEEE 754 spec, NaN is not equal to itself! Strange but true. Once again, the expression evaluates to true, and the loop spins forever.

Neal: So what can we learn from all of this?

Josh: Two things. First, floating point arithmetic is tricky. Floating point numbers aren’t the same as the real numbers that you learned about in school. Be very careful when you’re working with floating point, and never use it when integer arithmetic will do. And, give your variables good names. I tried to mislead you by calling the variable i, which suggests that it’s an integer.

Neal: I have two more loopers for our readers. Our thanks go to Ron Gabor, a reader from Herzliya, Israel, for sending us these fine puzzlers, and coming up with the “looper” concept.

Here are two while loops, each of which appears to do nothing, but can be made to loop forever by preceding it with the correct declaration. Can you figure out what declaration makes each loop spin forever? Both of these puzzlers can (and should) be solved without resorting to floating point.

// Problem 1
while (i != i + 0) ;

// Problem 2
while (i != 0) i >>>= 1;

In case you don’t have your Java Language Specification handy, the funny looking >>>= is the assignment operator corresponding to unsigned right shift. The solutions for these two loopers appear on pages 29-30.

Puzzler Three: A Dog without a bark

Neal: In the next group of puzzlers, we’ll show you a program and you tell us what it prints and why. And just to keep things interesting, we reserve the right to include programs that don’t compile, programs that throw exceptions, and programs whose behavior can vary from implementation to implementation.

Let’s start with this program. It has a simple class hierarchy and a single method in both the superclass and the subclass:

class Dog {
public static void bark() {
System.out.print(“woof “);

class Basenji extends Dog {
public static void bark() { }
public class Bark {
public static void main(String args[]) {
Dog woofer = new Dog();
Dog nipper = new Basenji();

Josh: What’s a Basenji anyway?

Neal: A Basenji is an African breed of dog that doesn’t bark. As you can see, Basenji extends Dog, but the bark() method in Basenji doesn’t do anything.

Josh: Got it. OK, what does this puzzler print? The solution is on page 30.

Puzzler Four: What’s In a Name?

Josh: This program has a “value class” representing a name, which consists of a first name and a last name. Two Name instances are equal if their first names are equal and their last names are equal. In the main() method, we create a Name instance, put it into a HashSet and then check to see if it’s in the set using a separate-but-equal Name instance.

public class Name {
private String first, last;
public Name(String first, String last) {
this.first = first;
this.last = last;

public boolean equals(Object o) {
if (!(o instanceof Name)) return false;
Name n = (Name)o;
return n.first.equals(first) && n.last.equals(last);

public static void main(String[] args) {
Set s = new HashSet();
s.add(new Name(“Donald”, “Duck”));
s.contains(new Name(“Donald”, “Duck”)));

Neal: Wait a minute; that won’t even compile! You need to import java.util.*.

Josh: Technically, you’re correct. I’ve omitted the import statement for brevity. From now on assume all of these programs have that import statement if needed.

Neal: OK, we’ll cut you some slack.

Josh: So, dear reader, what does the code print? (Turn to page 30 for the solution.)

Puzzler Five: Bad Code Pun Ahead

Neal: This program is pretty trivial. What does it print?

public class Trivial {
public static void main(String args[]) {
System.out.print(“H” + “a”);
System.out.print(‘H’ + ‘a’);

Josh: Very punny. I hope our esteemed and high-brow readers will still answer your question. (Solution on page 31.)

Puzzler six: Overloading Your Brain

Josh: Our next problem concerns overload resolution.

public class Confusing {
public Confusing(Object o) {
public Confusing(double[] dArray) {
System.out.println(“double array”);
public static void main(String args[]) {
new Confusing(null);

As you can see, the class has two constructors. Constructors don’t usually print anything, but these intentionally do so we can tell which one is invoked. The main program simply creates a new instance of the class by passing null to the constructor. Your mission, should you choose to accept it, is to figure out which constructor gets used. Ponder this one and then look at page 31 to see if you’re right.

Problem seven: Off Base

Neal: Like Puzzler Three, this puzzler concerns a simple type hierarchy. But unlike Puzzler Three, this one concerns a field rather than a method. What does it print? The solution’s over on page 31.

class Base {
public String name = “Base”;

class Derived extends Base {
private String name = “Derived”;

public class PrintName {
public static void main(String[] args) {
System.out.println(new Derived().name);

Puzzler Eight: One is the Loneliest Number

Josh: This problem concerns the singleton pattern, superficially at least:

public class Truth {
// Singleton pattern
public static final Truth INSTANCE = new Truth();
private Truth() { testify(); }

private static final boolean TRUTH = truth();
private static boolean truth() { return true; }
public static void testify() {
System.out.println(“The truth is: ” + TRUTH);

public static void main(String[] args) {

What does this print? To find the truth, turn to page 32.

Puzzlers Nine and Ten: Short Programs

Neal: OK, that was a bit of fun. We showed you programs and you figured out what they did. Now it’s your turn to do the heavy lifting.

Josh: In the next few problems we’ll describe a small task and it’s up to you to write a program that accomplishes the task. For these problems, there isn’t a single correct answer. Give yourself a point if your code is as clear and elegant as our solution.

  • Puzzler Nine: Write a method that takes a Vector of elements and returns a new Vector containing the same elements in the same order, with the second and subsequent occurrences of any duplicate elements removed. For example, if you pass in a Vector containing “Spam”, “Spam”, “sausage”, “eggs”, “Spam”, “Spam”, and “Spam”, you’ll get back a new Vector containing “Spam”, “sausage”, and “eggs”, in that order.
  • Puzzler Ten: Write a program that prints a line telling you how many times it has been run. The first time you run it, it should print “This is run number 0,” the second time it should print “This is run number 1,” and so forth.

Solution One

Neal: We started with two loop puzzlers to solve. Here’s the first loop:

while (i != i + 0);

Josh: Couldn’t we just set i equal to Double.NaN?

Neal: No, you dummy, you were supposed to solve these puzzlers without using any floating point.

Josh: Oh, well, how about this:

String i = “Buy Effective Java!”;

Neal: Oooh, clever… That turns the plus sign into the string concatenation operator. Then the int 0 is converted to the string “0″ and appended to the blatant plug.

Josh: Yep. The plus sign is overloaded, and operator overloading can be very misleading. It looks like addition, but it’s really string concatenation.

Neal: It’s even more misleading because I called the variable i. Using good variable, method, and class names are as important to the documentation of a program as good comments.

Solution Two

Neal: As you’ll recall, this was the loop:

while (i != 0) i >>>= 1;

Josh: I have no idea how to solve that one! For the shift to be legal, i has to be an integral type, and the unsigned right shift operator will produce a result closer to zero on each iteration.

Neal: That’s almost right, but there’s one small twist that throws a wrench in to your logic. The >>>= operator is an assignment operator, and assignment operators have a hidden cast in them. The cast can be a narrowing cast, which throws away information.

Josh: Huh?

Neal: OK, suppose you use this declaration:

short i = -1;

Here’s what happens. First, the value of i (0xFFFF) is promoted to an int; all arithmetic operations do that if their operands are of type short, byte, or char. The promotion involves sign extension, so the resulting value is 0xFFFFFFFF. This value is shifted right one bit without sign extension, which yields 0x7FFFFFFF. Now here’s the kicker: when this value is stored back into i, the implicit narrowing cast that I mentioned earlier chops off the high-order 16 bits, leaving 0xFFFF, and we’re back where we started.

Josh: Ouch! So assignment operators are pretty dangerous when you use them on short, byte, and char values?

Neal: Yep. You end up doing mixed mode arithmetic, which is always a tricky business. Worse, you end up doing a narrowing cast even though it doesn’t show up in the code.

Solution Three

Josh: Hmmm… Basenji extends Dog, but overrides the bark() method to do nothing. So the main program, which invokes the bark method on a Dog and then on a Basenji only prints woof once, right?

Neal: You’d think so, but that’s incorrect. I’m sure our readers noticed that the bark() methods are static. You don’t get dynamic dispatch on static methods. Static methods can never be overridden; they can only be hidden. In this program the bark() method in Basenji hides the bark() method in Dog. When you invoke the bark() method, the method to be invoked is selected at compile-time by the type of the qualifier. In this program, both variables are statically declared as Dogs. So the compiler makes the same decision in both cases, invoking the bark() method in Dog.

Josh: OK, I get it. How do you fix it?

Neal: Well, if you want dynamic dispatch, you should remove static from the method declarations.

Josh: So what is the moral?

Neal: The moral is that you cannot override static methods, you can only hide them. It’s a bad idea to hide static methods precisely because you can get into this kind of confusion. Also, you should never invoke a static method on an instance variable. When you invoke a static method, you should qualify it with the name of the type on which it was defined, rather than qualifying it with an expression. Otherwise, it looks like you’ll get dynamic dispatch.

Josh: OK, wise guy, if it’s such a bad idea to invoke static methods using an instance, why does the language allow it?

Neal: I’ve heard that this was a bug in an early version of the Java compiler, but by the time it was discovered there were already programs that depended on it. If we had the choice today, we would disallow it.

Solution Four

Neal: This one looks pretty easy. It puts Donald Duck into the hash set and then prints a boolean value indicating whether or not he’s in the set. It prints true, right?

Josh: Well, that’s a good guess, but, of course, it’s wrong. It turns out that the result can vary from implementation to implementation. As a practical matter, all the implementations we’re aware of will print false, so if that was your answer, give yourself half a point. The reason for this flaky behavior is that the Name class violates the hashCode() contract.

Neal: Wait a minute, how could it violate the hashCode() contract? There was no hashCode() method in the program!

Josh: That’s just the problem. The Name class overrides the equals() method but the hashCode() contract demands that equal objects must have equal hash codes. We’re putting a Name instance into a HashSet. How does the HashSet decide which bucket to place the entry into? It invokes hashCode(). But Name inherits its hashCode() method from Object, so it returns an identity-based hash code. Since the second Name instance has a different identity from the first, we can expect it to have a different identity hash code. So the HashSet looks in the wrong bucket and won’t find the entry.

Neal: Ouch. And how do I fix it?

Josh: Add a hashCode() method, of course. Here’s one that works, based on the recipe from my book:

public int hashCode() {
return 31 * first.hashCode() + last.hashCode();

The lesson is simple: Always override hashCode() method when you override equals(). Any time you see a class that overrides equals() but not hashCode() you should say, “Ah! There is a bug.”

Neal: I’ve made this mistake myself a couple of times. It’s very hard to track down a bug caused by this. Maybe we can add a warning to the compiler.

Josh: Amen to that. In the mean time, be sure to obey the general contract whenever you override a method that has one. Chapter 3 of my book discusses the general contracts for all the Object methods.

Solution Five

Josh: Easy. It concatenates “H” and “a” two different ways and prints the result. So I guess it prints HaHa.

Neal: Nice try. The correct answer is that it prints Ha169.

Josh: Surely you jest?

Neal: No, you see ‘H’ and ‘a’ are both character constants. The char type is an integral type, so the + operator in this case is addition, not concatenation. And, don’t call me Shirley!

Josh: That’s terribly confusing. How do we avoid this kind of trouble?

Neal: Well, I have two answers. If you want to do string concatenation, make sure that at least one of the arguments is a string. A common idiom is to put “” + at the beginning of a string concatenation expression:

System.out.print(“” + ‘H’ + ‘a’);

This ensures that all the subexpressions following the plus signs are converted to strings. The second answer is to avoid operator overloading because it can be confusing. In this case, the confusion arises from overloading of a built-in operator, so there’s nothing you can do about it. Perhaps that is a lesson for language designers?

Solution six

Neal: Hmmm… The argument passed to the constructor is the null Object reference, so I suppose it would have to match the first constructor. But wait, arrays are reference types too, so it could just as well match the second constructor. I don’t see any way that it could choose between them, so I suppose the constructor invocation is ambiguous, and a compiler error results.

Josh: Ah, but if you run the program, you’ll find that it prints double array.

Neal: But that doesn’t make any sense! If you told me the answer was Object, maybe I could buy that, but why should the compiler select the constructor that takes a double array rather than the one that takes Object?

Josh: In this case, both constructors are applicable and accessible, so the compiler selects the one that is most specific. Since array types are reference types, the type double[] inherits from Object. This means the constructor that takes a double array is more specific.

Neal: Bizarre. So how do we fix it?

Josh: Ideally you should make sure that the argument lists to constructors are so different that you don’t have this sort of ambiguity. For example, all constructors to a class could have different numbers of arguments. If this is impossible, make sure that multiple constructors that could be invoked with the same object references behave identically. Finally, if you have a class that fails on these two counts, you can cast the actual to select a desired constructor. For example, you could invoke Confusing(Object) on null as follows:

new Confusing((Object)null);

All of this applies to overloaded methods as well as constructors. Once again, it goes to show that overloading can be dangerous and should not be overused.

Solution seven

Josh: I don’t think that program will compile. There’s an error in class Derived. You’re not allowed to override name and give it more restrictive access — it’s private in Derived and public in Base.

Neal: Well, the program doesn’t compile, but not for the reason you said. There’s nothing wrong with class Derived because it doesn’t override name. Only methods can be overridden. Rather, Derived.name hides Base.name. That’s allowed, but as you can see, it often leads to confusion. The real error is in the main program: class PrintName is trying to access the private field name from class Derived. That’s not allowed, so there is a compile-time error in class PrintName.

Josh: So how do you fix it?

Neal: If you want overriding behavior, you can get it using access methods in place of visible fields:

class Base {
public String getName() { return “Base”; }

class Derived extends Base {
public String getName() { return “Derived”; }

public class PrintName {
public static void main(String[] args) {
System.out.println(new Derived().getName());

Josh: I notice that you made the access method in class Derived public.

Neal: Yep. It wouldn’t compile if it were private, for exactly the reason you suggested a moment ago. One lesson to learn from this problem is that hiding is generally a bad idea. You can hide variables, nested types, and even methods. The problem with hiding is that it leads to confusion in the mind of the reader. Are you using the hidden entity or the entity that is doing the hiding? Whenever you have hiding in a program, you have violated the principle of subsumption, which states that everything you can do with the base class you can do with the derived class. Subsumption is a part of our natural mental model of object-oriented programming, so whenever it is violated a program becomes harder to understand.

Solution Eight

Josh: If you tried running the program, you found out that it prints:

The truth is: false
The truth is: true

Neal: Hang on a sec, are you saying the program observes a final variable changing its value? I thought the whole point of declaring a variable final was that you could never change its value.

Josh: Yes, but you can observe the transition when the first (and only) assignment takes place, as this program does. Let’s trace its execution.

Neal: I’d rather see your execution.

Josh: Never mind that. The first thing that happens when this program executes is that the class Truth is initialized. The static initializers in Truth are processed in source order, beginning with the initialization of the field INSTANCE. The initializer for this field constructs a new Truth instance.

Normally, creating an instance of a class causes the class to get initialized before executing the constructor. In this case, however, we’re already in the midst of initializing the class. According to the language spec, this means that we skip the initialization of Truth that was triggered by creating the instance, and go straight to the constructor. When the constructor executes, the static field TRUTH hasn’t yet been initialized so it contains its default initial value, which is false. When the constructor invokes testify(), the program prints The truth is: false.

Then the static initialization of Truth completes by initializing the variable TRUTH to true. Finally, the testify() method is invoked from within the main() method. By then, all of the static initialization has finished, so the program prints The truth is: true.

Neal: It’s too bad the VM doesn’t throw an error when this happens. I’d rather get a runtime error than allow my program to use classes before they’re initialized.

Josh: Perhaps, but it’s too late to change the semantics of the language. This puzzler illustrates a problem in the design of many programming languages: coming up with a consistent, meaningful initialization sequence in the face of possible circularities.

The lesson for programmers is to watch out for circularities in class initialization sequences. For instance, it’s usually wrong to initialize a static field with an instance of a subclass. Unfortunately, this pattern arises naturally in the context of service provider frameworks. If you find yourself doing this, consider initializing the static field lazily. Techniques for lazy initialization are discussed in Item 48 of my brother’s book, “Effective Java Programming Language Guide.”

Solutions Nine And Ten

Josh: Believe it or not, you can solve Puzzlers Nine and Ten the Type-It way using J2SE 1.4. Here are two hints: look at the new LinkedHashSet and Preferences classes. You can download our solutions (and lots of other “Puzzler” code) from http://www.linux-mag.com/downloads/2003-03/puzzlers.

The Third Half of the Show

Josh: Well, let’s see how we did. Here’s a little table to help you interpret your score:

Neal: And now, for the real masochists out there, we have one last puzzler, and we won’t tell you the answer to this one. It’s very hard because it combines a number of subtle language questions into a single program. Don’t assume your compiler will give the right answer. What should this program print, and why?

class Twisted {
private final String name;
private void prname() {
Twisted(String name) {
this.name = name;
public static void main(String[] args) {
new Twisted(“main”).doit();
private void doit() {
new Twisted(“doit”) {
void f() { prname(); }

Here’s a hint: Pour yourself a stiff drink and cuddle up with your well-thumbed copy of “The Java Language Specification, Second Edition.” Read sections,, and 15.9.1. Now read them again. When you wake up, read them one last time and all will become clear.

Josh: I have no idea what that program does, but the lesson of this whole exercise is reasonably clear. Java is simple and elegant, but it does have a few sharp corners. Be aware of them and avoid them. Keep your programs simple. If your code isn’t clear, then it probably doesn’t do what you want it to.

Neal: Also, you should avoid all kinds of name reuse, except overriding. Hiding, shadowing, and overloading all lead to confusion. Two different entities should be given different names unless one is a method that overrides the other.

Josh: That’s it for today. If you have a puzzler for us, write it on the back of a twenty dollar bill and send it to me.

Neal: Or better yet, email it to us at javapuzzlers@sun.com. If we use it, we’ll give you credit. And last but not least, don’t code like my brother.

Josh: Don’t code like my brother.

10You probably cheat on your taxes too.
8-9Do you do anything else besides program computers?
7A wizard, a true star.
5-6You did better than my brother. And he resents it.
1-4Par for the course.
0You wonder what all this has to do with coffee.

Joshua Bloch is a Senior Staff Engineer at Sun Microsystems where he led the design and implementation of numerous Java platform features including the award-winning Java Collections Framework. He is the author of the bestselling, Jolt Award-winning “Effective Java Programming Language Guide.” He holds a Ph.D. from Carnegie-Mellon University and a B.S. from Columbia. Neal Gafter is a Senior Staff Engineer at Sun Microsystems where he is in charge of the Java compiler and language tools. He has worked in compilers since 1981. He holds a Ph.D. from the University of Rochester and a B.S. from Case Western.You can download the source code for these puzzlers and find eight more puzzlers at http://www.linux-mag.com/downloads/2003-03/puzzlers.

Comments are closed.