Java Language Pitfall - Misplaced semicolons and missing braces


Example

This is a mistake that causes real confusion for Java beginners, at least the first time that they do it. Instead of writing this:

if (feeling == HAPPY)
    System.out.println("Smile");
else
    System.out.println("Frown");

they accidentally write this:

if (feeling == HAPPY);
    System.out.println("Smile");
else
    System.out.println("Frown");

and are puzzled when the Java compiler tells them that the else is misplaced. The Java compiler with interpret the above as follows:

if (feeling == HAPPY)
    /*empty statement*/ ;
System.out.println("Smile");   // This is unconditional
else                           // This is misplaced.  A statement cannot
                               // start with 'else'
System.out.println("Frown");

In other cases, there will be no be compilation errors, but the code won't do what the programmer intends. For example:

for (int i = 0; i < 5; i++);
    System.out.println("Hello");

only prints "Hello" once. Once again, the spurious semicolon means that the body of the for loop is an empty statement. That means that the println call that follows is unconditional.

Another variation:

for (int i = 0; i < 5; i++);
    System.out.println("The number is " + i);

This will give a "Cannot find symbol" error for i. The presence of the spurious semicolon means that the println call is attempting to use i outside of its scope.

In those examples, there is a straight-forward solution: simply delete the spurious semicolon. However, there are some deeper lessons to be drawn from these examples:

  1. The semicolon in Java is not "syntactic noise". The presence or absence of a semicolon can change the meaning of your program. Don't just add them at the end of every line.

  2. Don't trust your code's indentation. In the Java language, extra whitespace at the beginning of a line is ignored by the compiler.

  3. Use an automatic indenter. All IDEs and many simple text editors understand how to correctly indent Java code.

  4. This is the most important lesson. Follow the latest Java style guidelines, and put braces around the "then" and "else" statements and the body statement of a loop. The open brace ({) should not be on a new line.

If the programmer followed the style rules then the if example with a misplaced semicolons would look like this:

if (feeling == HAPPY); {
    System.out.println("Smile");
} else {
    System.out.println("Frown");
}

That looks odd to an experienced eye. If you auto-indented that code, it would probably look like this:

if (feeling == HAPPY); {
                           System.out.println("Smile");
                       } else {
                           System.out.println("Frown");
                       }

which should stand out as wrong to even a beginner.