Shiklo Programming
EN
  • English
  • Español
  • Português
  • Deutsch
  • Français
  • 日本語
  • हिन्दी

Java Errors and Debugging

Every programmer writes code with mistakes; good programmers find them quickly. Java helps a lot, because many mistakes are caught before the program even runs. There are three kinds of errors, and each one is found in a different way. This last topic brings together what you have seen along the way, from Get Started to Exceptions.

Compile errors

A compile error means javac could not understand or accept your code, so no program was produced. The message gives the file, the line and the problem. Read the first error first: one mistake can cause several messages after it.

public class Main {
    public static void main(String[] args) {
        int count = "five";
        System.out.println(count);
    }
}
The compiler says
Main.java:3: error: incompatible types: String cannot be converted to int

The most common compile errors:

MessageUsual cause
';' expecteda missing semicolon at the end of the line before
cannot find symbola misspelled name, a missing import, or a variable used outside its scope
incompatible typesa value of the wrong type, as above
missing return statementa method with a return type that does not return on every path
class X is public, should be declared in a file named X.javathe class name and the file name differ
unreported exceptiona checked exception that is neither caught nor declared
public class Main {
    public static void main(String[] args) {
        String name = "Asha";
        System.out.println(nmae.length());
    }
}
The compiler says
Main.java:4: error: cannot find symbol

Our editor marks the line in the code and adds a hint in plain words below the compiler's message.

Runtime errors

A runtime error happens while the program runs: the code compiled, but something impossible happened, and Java throws an exception. Read the stack trace from the top: the exception's name and message, then the at lines with method names and line numbers. The first line that mentions your code is where to look:

public class Main {
    static int average(int[] values) {
        int sum = 0;
        for (int v : values) {
            sum += v;
        }
        return sum / values.length;
    }

    public static void main(String[] args) {
        System.out.println(average(new int[] {4, 8}));
        System.out.println(average(new int[0]));
    }
}
Output
6
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Main.average(Main.java:7)
	at Main.main(Main.java:12)

The trace shows that average was called from main at line 12, and the division failed at line 7 because the array was empty. The fix is to handle that case before dividing.

Logic errors and printing values

A logic error is the hardest kind: the program runs without any message but gives a wrong result. The simplest tool is to print the values of variables at important points and compare them with what you expected:

public class Main {
    public static void main(String[] args) {
        int[] prices = {120, 80, 45};
        int total = 0;
        for (int i = 1; i < prices.length; i++) {
            total += prices[i];
            System.out.println("debug: i=" + i + " total=" + total);
        }
        System.out.println("Total: " + total);
    }
}
Output
debug: i=1 total=80
debug: i=2 total=125
Total: 125

The debug lines show that the loop starts at i=1, so the first price is never added. Changing int i = 1 to int i = 0 fixes it. Remove the debug lines once the bug is gone.

assert

An assert statement checks something you believe is always true. Assertions are switched off by default and are switched on with java -ea Main in the terminal; then a false assertion stops the program with an AssertionError:

public class Main {
    static int discount(int price) {
        int result = price * 90 / 100;
        assert result <= price : "discount made the price higher";
        return result;
    }

    public static void main(String[] args) {
        System.out.println(discount(500));
    }
}
Output
450

A checklist for finding bugs

  1. Read the whole error message and find the line number.
  2. Check the line and the line before it.
  3. Print the values of the variables involved.
  4. Test with small, simple input where you know the right answer.
  5. Change one thing at a time and run again.

Congratulations on reaching the end of the Java tutorial. Keep practising: pick a small project such as a quiz, a to-do list saved in a file, or a simple bank account, and build it step by step with what you have learned.

Practice exercises

  1. Write a program with three different compile errors and fix them one by one, reading each message.
  2. Make a program that causes a NullPointerException and find the line from the stack trace.
  3. Add debug prints to a loop that sums only the odd numbers from 1 to 10 and check each step.