RTFS – Read the Fabulous Screen

RTFS or Read the Fabulous Screen. Cartoon of man staring at a computer screen

In last week’s post I looked at the acronym “RTFM”. This stands for “Read the Fabulous Manual”, with the “F” being replaced with friendly, fine, fantastic, famous or any other word starting with an appropriate F.

There is a lesser-known, but similar acronym “RTFS” – “Read the Fabulous Screen”. In this post, I’ll be looking at the acronym specifically from the perspective of the output of the Java compiler.

Java Compiler Messages

Coming from a C/C++ background, one of the things that really struck me when I started coding in Java was the quality and clarity of the compiler error messages. In general I found them much easier to read and understand than the C/C++ compiler messages that I was used to. It could have been from growing maturity and coding experience, but I’m convinced that the Java compiler messages are fantastically useful, and deserve to be read carefully, i.e. “RTFS”. They point you close to the exact location of the error, including the line number and column.

A Simple Example

Let’s look at a small Java program similar in size to the standard “Hello, world” class.

public class ExampleClass {

    public static void main (String args[]) {

        int x;
        System.out.println("x = " + x);

        ExampleClass obj = new ExampleClass();
        System.out.println(obj);
    }

} // end of class

Nothing exotic or complicated about this class definition.

Let’s say that when we save this file, we make a spelling mistake and save it as ExamplClass.java. Easy enough to do. What’s the error message when compiling ExamplClass.java?

ExamplClass.java:4: error: class ExampleClass is public, should be declared in a file named ExampleClass.java
public class ExampleClass {
       ^
1 error

The message is straightforward and plain. We know that public classes must be saved in a file with the identical name of the class. And to put the cherry on the cake, the ^ points to the word class.

So we rename the file to ExampleClass.java and recompile.

Now another error message pops up:

ExampleClass.java:6: error: variable x might not have been initialized
        System.out.println("x = " + x);
                                    ^
1 error

Again, the compiler does a sterling job pointing you to the right line number (6) and column (where the caret points), and tells you that variable x might not have been initialized. Ahh! You remember that all local variables are created on the stack and are not initialised. So you assign a suitable value to x and recompile. Success eventually!

An Override Error

The last line in the main() method is System.out.println(obj); Clearly we wanted to print some information about the object. Behind the scenes the toString() method of the Object class is called. If we want to override this toString() method, we can easily do it as follows:

@Override public String toString() {
    return "I'm an ExampleClass object";
}

What if we made another typo, and spelt toString() with a capital letter T as in:

@Override public String ToString() {
    return "I'm an ExampleClass object";
}

The error message is again very obvious and points you directly to the culprit:

ExampleClass.java:12: error: method does not override or implement a method from a supertype
    @Override public String ToString() {
    ^
1 error

A Few More Errors

The next two coding errors generate a lot of output from the compiler, so be warned.

Let’s say we forget the opening curly brace on the first line of the class definition.

public class ExampleClass  // missing opening brace

The compiler output is the following:

ExampleClass.java:2: error: '{' expected
public class ExampleClass
                         ^
ExampleClass.java:4: error: class, interface, enum, or record expected
    public static void main (String args[])
                  ^
ExampleClass.java:7: error: class, interface, enum, or record expected
        System.out.println("x = " + x);
        ^
ExampleClass.java:9: error: class, interface, enum, or record expected
        ExampleClass obj = new ExampleClass();
        ^
ExampleClass.java:10: error: class, interface, enum, or record expected
        System.out.println("obj = " + obj);
        ^
ExampleClass.java:11: error: class, interface, enum, or record expected
    }
    ^
ExampleClass.java:13: error: class, interface, enum, or record expected
    @Override public String toString() {
                     ^
ExampleClass.java:15: error: class, interface, enum, or record expected
    }
    ^
8 errors

Lots of errors, but only the first one matters. Often the first error causes a cascade of what appear to be erroneous error messages.

The compiler again points you to the correct line number (2) and column (where the caret points):

ExampleClass.java:2: error: '{' expected
public class ExampleClass
                         ^

Let’s say we forget the opening curly brace on the main() method.

public static void main (String args[]) // missing opening brace

Again, a flood of error messages. This is a little more difficult to interpret. The first error says the compiler is expecting a semi-colon: error: ';' expected. Obviously we know that we don’t put a semi-colon after a method header unless it’s an abstract method, so that’s a big clue.

ExampleClass.java:4: error: ';' expected
    public static void main (String args[])
                                           ^
ExampleClass.java:7: error: <identifier> expected
        System.out.println("x = " + x);
                          ^
ExampleClass.java:7: error: illegal start of type
        System.out.println("x = " + x);
                           ^
ExampleClass.java:10: error: <identifier> expected
        System.out.println("obj = " + obj);
                          ^
ExampleClass.java:10: error: illegal start of type
        System.out.println("obj = " + obj);
                           ^
ExampleClass.java:13: error: class, interface, enum, or record expected
    @Override public String toString() {
                     ^
ExampleClass.java:15: error: class, interface, enum, or record expected
    }
    ^
7 errors

The last two lines here (and just about all the lines of the previous errors) were error: class, interface, enum, or record expected. This is a clear indication that you’re missing an opening brace somewhere important.

If we leave out a closing brace, we’ll normally get an error along the lines of :

ExampleClass.java:16: error: reached end of file while parsing
    }
     ^
1 error

An Error Running the Compiler

I’m assuming here that we are compiling from the command line. I know most developers use an IDE of some description, but all IDEs capture the output of the javac compiler. So the compiler error messages will be the same.

There are some errors that the IDE prevents you from making, such as forgetting to add the .java extension to the filename. Let’s say we forget the extension when compiling from the command line:

C:\dev\ExampleClass>javac ExampleClass
error: Class names, 'ExampleClass', are only accepted if annotation processing is explicitly requested
1 error

This is a slightly less understandable error message, but once you read and think about it a bit, the compiler has told you that you haven’t passed it a file name, but rather the class name.

Ending Off

From all of these examples, it should be fairly obviously that if we just take the time to read the screen carefully, we should be able to solve all of our compilation errors.

In another post, I’ll look at runtime errors and the dreaded stack trace.

What do you think about RTFS? Share your comments and Java experiences.

Stay safe, and I’ll see you next week!

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.