JAVA • DEBUGGING AND TESTING

Common Java Exceptions — Recognize common exceptions (NullPointerException, IndexOutOfBoundsException, NumberFormatException)

Learn to identify and fix the three runtime errors that trip up every Java programmer.

Historical Context & Motivation

When you write a Java program, the compiler catches many mistakes before the program ever runs — things like missing semicolons or misspelled variable names. However, some errors only appear while the program is actually executing. These runtime problems are called exceptions, and they have been a core part of Java since the language was first released. Understanding where exceptions came from helps explain why Java handles errors the way it does today.

1972
C Language & Error Codes
The C programming language used simple integer error codes to signal problems. Programmers had to manually check return values after every function call, making it easy to forget a check and let bugs slip through.
1985
C++ Introduces Exceptions
C++ added a try/catch mechanism so programs could automatically jump to error-handling code when something went wrong. This idea of "throwing" and "catching" errors became a model for later languages.
1995
Java 1.0 Released
James Gosling and the team at Sun Microsystems released Java with a built-in exception hierarchy. Classes like NullPointerException, ArrayIndexOutOfBoundsException, and NumberFormatException were present from day one.
2004
Java 5 — Improved Stack Traces
Java 5 added generics and enhanced error messages in stack traces, making it significantly easier for developers to locate the exact line of code where an exception occurred.
2017+
Modern IDEs & Helpful Messages
Modern Java versions and IDEs like IntelliJ IDEA now provide detailed, human-readable exception messages, sometimes suggesting the exact fix. Despite these improvements, the same three classic exceptions remain the most common.

Even with decades of language improvements, NullPointerException, IndexOutOfBoundsException, and NumberFormatException remain the errors that Java programmers encounter most often. How can you learn to spot these exceptions before they crash your program, and what does each one actually mean? That is exactly what this lesson explores.

Core Principles & Definitions

Before diving into specific exceptions, you need to understand a few foundational ideas about how Java handles errors at runtime. Java organizes all errors into a class hierarchy, and the three exceptions we focus on are all unchecked exceptions — meaning the compiler does not force you to handle them with try/catch blocks. They extend RuntimeException, and they signal mistakes in your logic rather than external problems like missing files.

1

NullPointerException (NPE)

Thrown when you try to use an object reference that points to null. Calling a method, accessing a field, or indexing an array on a null reference all trigger this exception.
2

IndexOutOfBoundsException

Thrown when you access an array or list with an index that is negative or equal to/greater than the length. The two main subtypes are ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException.
3

NumberFormatException

Thrown when you try to convert a string to a number but the string does not contain a valid numeric format. For example, Integer.parseInt("abc") will always throw this exception.
4

Unchecked vs. Checked

All three exceptions are unchecked (extend RuntimeException). The compiler won't warn you about them. You must use good coding practices — like null checks and input validation — to prevent them.
5

Stack Traces Are Your Friend

When an exception occurs, Java prints a stack trace showing the exception type, a message, and the exact file and line number. Reading the first line of the trace almost always tells you what went wrong.
✦ KEY TAKEAWAY
Think of exceptions like warning lights on a car dashboard. A NullPointerException is like trying to turn the steering wheel when there is no steering wheel installed — you are using something that does not exist. An IndexOutOfBoundsException is like trying to sit in seat number 6 on a bus that only has 5 seats. A NumberFormatException is like putting diesel fuel into a gasoline engine — the format does not match what the system expects.

Visual Explanation — The Exception Hierarchy

Java organizes all exceptions into a tree-like class hierarchy. Every exception you will encounter inherits from the Throwable class. The diagram below shows where our three target exceptions sit within this hierarchy. Notice that all three live under RuntimeException, which means they are unchecked — the compiler will not remind you to handle them.

The three exceptions highlighted in color — NullPointerException, IndexOutOfBoundsException, and NumberFormatException — all descend from RuntimeException, making them unchecked exceptions.

When you see an error message in the console, the first word before the colon is the exception class name. If it says java.lang.NullPointerException, you know immediately that some variable was null when your code tried to use it. If you see java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5, you know you tried to access position 5 in an array that only has positions 0 through 4. Learning to read these names is the fastest path to fixing bugs.

How Each Exception Works Under the Hood

NullPointerException — The Missing Reference

In Java, every object variable is really a reference — an address pointing to an object stored in memory. When you declare a variable like String name; without assigning a value, its default value is null, meaning it points to nothing. If you then call name.length(), the JVM cannot find any object to execute that method on, so it throws a NullPointerException. Common triggers include forgetting to initialize variables, methods that return null unexpectedly, and uninitialized array elements of object types.

IndexOutOfBoundsException — Going Past the Edge

Java arrays and ArrayLists use zero-based indexing, meaning the first element is at index 0 and the last element is at index length − 1. If an array has 5 elements, valid indices are 0, 1, 2, 3, and 4. Accessing index 5 — or any negative index — causes an ArrayIndexOutOfBoundsException. The same principle applies to Strings: calling charAt(10) on a 5-character string throws a StringIndexOutOfBoundsException. The most common cause is an off-by-one error in a loop, such as using <= instead of < in the loop condition.

NumberFormatException — Bad Input, Wrong Type

Methods like Integer.parseInt() and Double.parseDouble() convert text into numbers. They examine each character and build a numeric value. If any character is not a valid digit (or sign/decimal point where expected), the method throws a NumberFormatException. This commonly happens when reading user input from the console or a file. Strings like "12.5" will fail with parseInt (because it expects an integer), and empty strings "" will always fail with any parsing method.

Each panel shows a triggering code snippet above and the prevention strategy below. The golden rule: validate before you use.

Detailed Breakdown — Triggers, Messages, and Fixes

Each exception has distinctive patterns in how it appears, what causes it, and how to fix it. The table below gives you a quick reference card. Memorizing these patterns will help you diagnose bugs in seconds rather than minutes.

Quick reference: common exceptions, their triggers, and fixes
ExceptionCommon TriggersTypical Error MessagePrevention Strategy
NullPointerExceptionCalling a method on a null reference; accessing a field of null; using null in an array index expressionCannot invoke "String.length()" because "str" is nullCheck for null before use: if (obj != null); initialize variables at declaration
ArrayIndexOutOfBoundsExceptionUsing index ≥ array.length; using negative index; off-by-one error in for loopIndex 5 out of bounds for length 5Use i < array.length in loops; use for-each loops when possible
StringIndexOutOfBoundsExceptionCalling charAt(), substring() with an index beyond string length or negativeString index out of range: 10Check str.length() before accessing characters
NumberFormatExceptionParsing non-numeric strings; parsing empty strings; parsing strings with spaces or special charactersFor input string: "abc"Wrap parsing in try/catch; validate input with regex or str.matches("\\d+")
🔍 Reading a Stack Trace
When an exception crashes your program, Java prints a stack trace. The first line shows the exception type and message. Below it are lines starting with at that show the call chain. Look at the topmost line that mentions your own class file — that is the exact line where the error happened. Modern Java (since version 14) even tells you which specific variable was null in an NPE.

Notice the pattern across all three exceptions: each one is caused by your code making an invalid assumption about data. With NPE, you assume a variable is not null. With index-out-of-bounds, you assume an index is within range. With NFE, you assume a string contains only digits. The solution is always the same principle — validate your assumptions before acting on them.

Worked Example — Debugging a Student Grade Calculator

Imagine you have written a program that reads student names and grade strings from an array, converts the grades to integers, and prints the average. The code below contains all three exception types. Let us walk through identifying and fixing each one.

Finding and Fixing Three Exceptions in One Program
1
Step 1 — Read the Original CodeThe program is: String[] names = {"Alice", "Bob", null, "Diana"}; String[] grades = {"95", "87", "hello", "76"}; The code loops with for (int i = 0; i <= names.length; i++) and inside the loop calls names[i].toUpperCase() and Integer.parseInt(grades[i]). We need to identify every potential exception.
2
Step 2 — Spot the IndexOutOfBoundsExceptionThe loop condition is i <= names.length. Since names.length is 4, the loop will execute when i = 4. But the last valid index is 3 (indices 0, 1, 2, 3). This is a classic off-by-one error.
Fix: change <= to < → i < names.length
3
Step 3 — Spot the NullPointerExceptionAt index 2, names[2] is null. When the code calls names[2].toUpperCase(), it tries to invoke a method on null, triggering a NullPointerException.
Fix: add a null check → if (names[i] != null) { names[i].toUpperCase(); }
4
Step 4 — Spot the NumberFormatExceptionAt index 2, grades[2] is "hello". When Integer.parseInt("hello") is called, Java cannot convert alphabetic characters to an integer, throwing a NumberFormatException.
Fix: wrap in try/catch → try { int g = Integer.parseInt(grades[i]); } catch (NumberFormatException e) { /* handle */ }
5
Step 5 — Write the Corrected CodeThe corrected loop: for (int i = 0; i < names.length; i++) { if (names[i] != null) { System.out.println(names[i].toUpperCase()); } try { int g = Integer.parseInt(grades[i]); } catch (NumberFormatException e) { System.out.println("Invalid grade: " + grades[i]); } } This version prevents all three exceptions by validating assumptions before acting on them.
All three exceptions are now prevented through bounds checking, null checking, and try/catch.

Comparing the Three Exceptions

While all three exceptions share the trait of being unchecked runtime exceptions, they differ in their root causes, the data types involved, and the best strategies for prevention. The table below highlights these differences to help you quickly identify which exception you are dealing with when debugging.

Side-by-side comparison of the three common Java exceptions
FeatureNullPointerExceptionIndexOutOfBoundsExceptionNumberFormatException
Root CauseUsing a reference that is nullAccessing an invalid indexParsing a non-numeric string
Data Types InvolvedAny object typeArrays, Strings, ListsStrings → numeric types
Best PreventionNull checks or OptionalBounds checks or for-each loopstry/catch or regex validation
When It HappensAnytime — method calls, field accessDuring index-based accessDuring type conversion
FrequencyMost common Java exception overallVery common in loopsCommon with user input
✦ KEY TAKEAWAY
Think of these three exceptions as three different types of locks on doors. A NullPointerException means there is no door at all — you are reaching for a handle that does not exist. An IndexOutOfBoundsException means you are trying to open door number 10 in a hallway that only has 5 doors. A NumberFormatException means you are trying to insert a square key into a round lock — the shape (format) does not match. In every case, the fix is to check before you act.

Connection to Advanced Error Handling

The three exceptions covered in this lesson are just the starting point. As you advance in Java, you will encounter more sophisticated approaches to error handling. Understanding the basics well prepares you for these more powerful techniques.

From basic exception recognition to advanced error handling
What You Know NowWhat Comes Next
Checking for null with if-statementsUsing Optional<T> to eliminate null references entirely (Java 8+)
Catching specific exceptions with try/catchMulti-catch blocks (catch (NPE | NFE e)), try-with-resources for files and streams
Recognizing runtime exceptions from error messagesCreating your own custom exception classes to represent domain-specific errors
Manually testing code and reading stack tracesWriting unit tests with JUnit that deliberately trigger exceptions using assertThrows()
Preventing individual exceptions with checksDefensive programming patterns and input validation frameworks

In AP Computer Science A, you are expected to recognize these three exceptions and explain what causes them. In college-level Java courses, you will go further — learning to design exception hierarchies, use logging frameworks, and write robust applications that handle errors gracefully instead of crashing. The mental model you build now — identify the assumption, validate it, then act — will serve you throughout your programming career.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Explain in your own words what the difference is between a NullPointerException and an IndexOutOfBoundsException. Both are runtime exceptions — so how are their causes fundamentally different?
PROBLEM 2 — BASIC CALCULATION
Consider the following code: int[] scores = {88, 92, 75, 100}; System.out.println(scores[4]); What exception will be thrown, and why? What is the valid range of indices for this array?
PROBLEM 3 — INTERMEDIATE
The following code is supposed to compute the sum of numeric values from user input. Identify all possible exceptions and rewrite the code to handle them: String[] inputs = {"10", null, "abc", "25"}; int sum = 0; for (int i = 0; i <= inputs.length; i++) { sum += Integer.parseInt(inputs[i].trim()); }
PROBLEM 4 — APPLIED
You are building a student registration system. A method receives a student's name (String) and their age as a String from a web form. Write a method called registerStudent(String name, String ageStr) that prints a welcome message with the student's name and age. It should safely handle the case where name is null, where ageStr is null, and where ageStr is not a valid integer.
PROBLEM 5 — CRITICAL THINKING
Some programmers argue that you should never use try/catch to handle NullPointerException or IndexOutOfBoundsException — instead, you should prevent them with if-checks. However, for NumberFormatException, try/catch is considered acceptable. Why do you think the Java community treats these exceptions differently? Explain when using try/catch is appropriate and when it is a sign of poor design.

Lesson Summary

Java's three most common runtime exceptions are NullPointerException (triggered by using a null reference), IndexOutOfBoundsException (triggered by accessing an invalid array, list, or string index), and NumberFormatException (triggered by converting a non-numeric string to a number). All three are unchecked exceptions that extend RuntimeException, meaning the compiler will not warn you about them.

The universal prevention strategy is to validate assumptions before acting on them: perform null checks before calling methods on objects, verify index bounds before accessing elements (remember that valid indices go from 0 to length − 1), and use try/catch or input validation when parsing strings to numbers. Learning to read stack traces — especially the first line showing the exception type and the topmost line referencing your code — is the fastest way to diagnose and fix these errors.

Varsity Tutors • Java • Common Java Exceptions — Recognize common exceptions (NullPointerException, IndexOutOfBoundsException, NumberFormatException)