Compilation errors
Compilers are notorious for their obscure error messages like “not a statement” that leave you wondering what they mean. Java is the most widely used language for teaching and learning introductory programming, and most students and teachers use the Sun SDK (System Development Kit) either directly or indirectly through a development environment like BlueJ or DrJava. The error messages produced by this compiler are terse and many novices find it difficult to achieve even syntactically correct programs. This document is a guide to understanding and fixing errors in Java.
There are three modules relating to errors discovered at compilation time: Syntax Errors in Java, Semantic Errors in Java and Structural Errors in Java. There are two modules on exceptions (errors discovered when the program is run): Exceptions in Java and Executing a Java Program. Since many errors arise from misunderstandings of Assignment and Equality in Java, there is a module that explains how they work with reference semantics. Finally, module Debugging Java Programs Without a Debugger will help you debug Java programs.
The Eclipse development environment has its own compiler for Java. While the environment is not as elementary as those intended for novices, it has much to recommend it—even in introductory courses—because of its superior error messages and its support for identifying and correcting syntax errors. The compiler is incremental meaning that it checks the correctness of your program as you type. Eclipse error message are different from those of the Sun SDK and will be presented alongside them.
If you doubt that an error message is correct, you can consult the formal definition of the Java language which is contained in the book The Java Language Specification by James Gosling, Bill Joy, Guy L. Steele Jr. and Gilad Bracha. It can also be downloaded from http://java.sun.com/docs/books/jls/index.html.
Before we discuss the various errors, it is important to understand that compilers are not very good at recovering from errors. Frequently, a single small mistake will cause the compiler to issue a cascade of messages. For example, in the following code, we forgot to write the closing brace of the method
f
:class MyClass {
void f() {
int n = 10;
// Error, closing brace is missing
void g() {
int m = 20;
}
}
An attempt to compile the program results in three error messages:
MyClass.java:5: illegal start of expression
void g() {
^
MyClass.java:8: ';' expected
}
^
MyClass.java:9: '}' expected
^
Do not invest any effort in trying to fix multiple error messages! Concentrate on fixing the first error and then recompile.
Eclipse: Syntax error, insert "}" to complete MethodBody. Eclipse is much better at diagnosing this error and produces only one message.
Runtime errors
When the Java interpreter encounters an error during runtime it throws an exception and prints a stack trace showing the entire call stack—the list of methods called from the main program until the statement that caused the exception.1 Consider the following program:
class Test {
public static void main(String[] args) {
String s = "Hello world";
System.out.println(s.substring(10,12));
}
}
We are trying to extract a substring of the string
s
but the upper index 12
is not within the string. Attempting to execute this code will cause an exception to be thrown:Exception in thread "main"
java.lang.StringIndexOutOfBoundsException:
String index out of range: 12
at java.lang.String.substring(Unknown Source)
at Test.main(Test.java:4)
The exception was thrown from within the library class
String
during the execution of the method substring
. This method was called at line 4
of method main
in the class Test
. It is unlikely that there is an error that causes an exception in a well established class of the Java library like String
; more likely, the String
class itself identified the error and threw the exception explicitly, so we are advised to seek the error starting at the deepest method of our own program.The calls in the stack trace are listed in reverse order of invocation, that is, the first call listed is the deepest method (where the exception occurred), while the last call listed is the shallowest method, namely
main
.Exceptions can be caught by writing a block of code called an exception handler that will be executed when an exception is thrown.2 Exception handlers are discussed in textbooks on the Java language; here we limit ourselves to explaining the exceptions that indicate programming errors. We further limit ourselves to exceptions commonly thrown by the language core; classes in the API define their own exceptions and these are explained in the API documentation.
No comments:
Post a Comment