Java Debugging
In this page:
Reading a Stack Trace
When an uncaught exception crashes a program, Java prints a stack trace: the exception type, its message, and the chain of method calls that led to it, listed innermost-first. The line numbers in each 'at ClassName.method(File.java:N)' entry point straight to the exact line that failed, and the cause is usually in the top-most frame belonging to your own code rather than a JDK internal class.
Example: Reading a Stack Trace
public class Main {
static void level2() {
throw new RuntimeException("Something broke");
}
static void level1() {
level2();
}
public static void main(String[] args) {
level1(); // uncaught: prints a stack trace, innermost call first
}
}
Login to try C/C++/Java/PHP code in the editor
Debugging with println
Sprinkling System.out.println() calls at key points in a method is a quick way to inspect variable values without setting up a debugger, especially for a one-off check. It's blunt and requires editing the source and rerunning, so it doesn't scale well for tracking down subtle bugs, but it remains the fastest first step for many developers.
Example: Debugging with println
public class Main {
public static void main(String[] args) {
int x = 5;
System.out.println("x = " + x); // quick inspection, no debugger needed
x = x * 2;
System.out.println("x after doubling = " + x);
}
}
Login to try C/C++/Java/PHP code in the editor
Using a Debugger and Breakpoints
A real debugger lets you pause execution at a breakpoint and inspect every variable's live value without modifying the code, which println debugging can't do. Step Over runs the current line and moves to the next one in the same method, Step Into follows execution down into a called method, and Step Out finishes the current method early and returns you to its caller.
Example: Using a Debugger and Breakpoints
public class Main {
public static void main(String[] args) {
int total = 0;
for (int i = 1; i <= 3; i++) {
total += i; // a breakpoint here lets you inspect total live
}
System.out.println(total);
}
}
Login to try C/C++/Java/PHP code in the editor
Common IDE Debugger Features
Modern IDEs add conditional breakpoints (pause only when an expression is true, useful inside a loop that runs thousands of times), watch expressions that track a variable's value across the whole session, and an interactive evaluation console for testing an expression mid-pause without editing the source. These features turn debugging from guesswork into a controlled inspection process.
Example: Common IDE Debugger Features
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
if (i == 500) { // conditional breakpoint would pause only here
System.out.println("Reached 500");
}
}
}
}
Login to try C/C++/Java/PHP code in the editor
Compile Errors vs Runtime Exceptions vs Logic Bugs
A compile-time error means the code never even runs (a missing semicolon, wrong type, unresolved symbol) and the compiler reports it before anything executes. A runtime exception means the code compiled fine but something went wrong while running (dividing by zero, a null reference) and Java reports it via a stack trace. A logic bug is the hardest of the three: the program compiles and runs without any error at all, it just silently produces the wrong answer, which is why deliberate debugging technique matters most here.
Example: Compile Errors vs Runtime Exceptions vs Logic Bugs
public class Main {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
try {
System.out.println(arr[5]); // runtime exception, not a compile error
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Runtime exception caught");
}
System.out.println(2 + 2); // if this printed 5, that'd be a logic bug
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: