Common Java Errors and How to Fix Them (With Code Examples)

Common Errors in Java and its fixes

Java errors are problems that stop your code from compiling, crashing it while running, or making it produce the wrong output. They fall into three main groups: compile-time errors (caught by the compiler before the program runs), runtime errors (thrown by the JVM during execution), and logic errors (the code runs fine but gives wrong results). Most beginner errors in Java are runtime exceptions like NullPointerException, ArrayIndexOutOfBoundsException, and NumberFormatException.

If you are a student learning Java, you will run into these errors a lot. That is normal. Every working coder has stared at the same red text in their IDE at some point. The good news is that almost every common Java error has a clear cause and a clean fix. Once you know what each error means and how it shows up in your code, you can spot the problem in seconds instead of hours.

“This guide walks you through the 8 most common Java errors students face in homework and projects, with simple explanations, real code examples, and the exact fix for each one. If you are stuck on a tricky bug in your assignment, our Java homework help service has you covered.”

Compile-Time vs Runtime vs Logic Errors

Before we look at specific errors, you need to understand the three big buckets. Knowing which type of error you are dealing with tells you where to look for the fix.

A compile-time error happens before your program even starts running. The Java compiler scans your code, finds a problem like a missing semicolon or a wrong variable name, and refuses to build the .class file. These errors are the easiest to fix because the compiler points right at the line.

A runtime error sneaks past the compiler. Your code looks fine on paper, so the JVM starts running it. But somewhere during execution, the program tries to do something illegal, like divide by zero or open a file that does not exist. The JVM throws an exception and your program crashes unless you catch it.

A logic error is the trickiest type. The code compiles, runs all the way through, and gives you an answer. The problem is that the answer is wrong. Maybe you used + instead of -, or your loop runs one time too many. The compiler cannot help you here. You have to test, trace, and debug yourself.

Here is a quick table that lays out the differences:

FeatureCompile-Time ErrorRuntime ErrorLogic Error
When it happensBefore the code runsWhile the code is runningAfter the code finishes
Who catches itJava compilerJVMYou, by testing
Common causeBad syntax, typos, missing bracketsBad input, null values, bad mathWrong formula or condition
ExampleMissing ; at end of lineNullPointerExceptionReversing a number with / instead of %
Difficulty to fixEasyMediumHard
Stops the program?Yes, will not compileYes, crashes mid-runNo, runs but gives wrong output

Most of the errors covered in this guide are runtime errors, since those are the ones that show up after you think your code is working.

NullPointerException

This is the single most common Java error you will ever see. A NullPointerException (often shortened to NPE) happens when you try to use an object that has not been given a value yet. In Java, an object variable that has no value is called null. If you call a method on a null object or try to read its fields, the JVM throws a NullPointerException and your program crashes.

Code Example:

				
					public class NullExample {
    public static void main(String[] args) {
        String name = null;
        System.out.println(name.length()); // NullPointerException here
    }
}
				
			

In the code above, the variable name was set to null. When we call name.length(), there is no actual String object to work with, so the JVM throws the error.

Fix 1: Check for null before using the object

The simplest fix is to add an if check before you call any method.

				
					String name = null;
if (name != null) {
    System.out.println(name.length());
} else {
    System.out.println("Name is empty");
}
				
			

Fix 2: Initialize the variable with a real value

If your variable should always have a value, just give it one when you declare it.

				
					String name = "CodingZap";
System.out.println(name.length()); // Works fine, prints 9
				
			

Fix 3: Use Optional for safer code

Java 8 added the Optional class, which forces you to think about whether a value might be missing.

				
					import java.util.Optional;

Optional<String> name = Optional.ofNullable(getName());
name.ifPresent(n -> System.out.println(n.length()));
				
			

A good habit is to never trust outside data. If a method returns an object, ask yourself whether that method could return null. If yes, check it first.

ArrayIndexOutOfBoundsException

This error shows up when you try to read or write a position in an array that does not exist. In Java, arrays are numbered starting at 0. So if you create an array of size 5, the valid positions are 0, 1, 2, 3, and 4. Trying to use position 5 or higher, or any negative number, throws an ArrayIndexOutOfBoundsException.

Code Example:

				
					public class ArrayExample {
    public static void main(String[] args) {
        int[] nums = {10, 20, 30, 40, 50};
        System.out.println(nums[5]); // ArrayIndexOutOfBoundsException
    }
}
				
			

The array nums has five elements at positions 0 through 4. When we ask for nums[5], the JVM throws the error because that position does not exist.

Fix 1: Use array.length in your loops

When you loop through an array, always use the length property instead of a hardcoded number.

				
					int[] nums = {10, 20, 30, 40, 50};
for (int i = 0; i < nums.length; i++) {
    System.out.println(nums[i]);
}
				
			

Fix 2: Check the index before access

If the index comes from user input or another method, check it first.

				
					int index = 5;
if (index >= 0 && index < nums.length) {
    System.out.println(nums[index]);
} else {
    System.out.println("Index is out of range");
}
				
			

Fix 3: Use a for-each loop when you do not need the index

If you just want to read each value, the for-each loop skips the index problem entirely.

				
					for (int n : nums) {
    System.out.println(n);
}
				
			

A common mistake students make is writing i <= nums.length instead of i < nums.length. That single character difference causes the error every time.

NumberFormatException

A NumberFormatException is a runtime error that happens when you try to turn a String into a number, but the String does not actually hold a valid number. This is one of the most common errors when you take input from a user and forget to clean it up first.

Code Example:

				
					public class NumberExample {
    public static void main(String[] args) {
        String input = "one";
        int number = Integer.parseInt(input); // NumberFormatException
        System.out.println(number);
    }
}
				
			

Here, the String "one" is a word, not a digit. When Integer.parseInt() tries to convert it, the JVM throws the error.

Common causes you should watch for:

  • Words mixed with numbers, like "45AB" or "one1"
  • Empty strings "" or strings with only spaces " "
  • A null value passed to parseInt()
  • Numbers too big for the data type, like "999999999999" for an int
  • Wrong radix base when parsing binary or hexadecimal values

Fix 1: Print the input first to see what you are working with

				
					String input = " 123 ";
System.out.println("Raw input: [" + input + "]");
int number = Integer.parseInt(input); // Still fails because of spaces
				
			

When you print the raw input, you can see if there are hidden spaces or weird characters.

Fix 2: Use trim() to remove extra spaces

				
					String input = " 123 ";
input = input.trim();
int number = Integer.parseInt(input);
System.out.println("Number: " + number); // Works, prints 123
				
			

The trim() method strips spaces from both ends of the String.

Fix 3: Wrap parsing in a try-catch block

This is the safest method, because it catches the error no matter what the bad input was.

				
					String input = "twoAB";
try {
    int number = Integer.parseInt(input);
    System.out.println("Number: " + number);
} catch (NumberFormatException e) {
    System.out.println("That is not a valid number: " + input);
}
				
			

When the bad input comes in, the catch block runs instead of crashing the program. This is the method most pro coders use in production code.

ClassCastException

A ClassCastException is thrown when you try to force an object to be a type it is not. This usually happens with collections or when you cast between parent and child classes in inheritance.

Code Example:

				
					public class CastExample {
    public static void main(String[] args) {
        Object obj = "Hello";
        Integer num = (Integer) obj; // ClassCastException
        System.out.println(num);
    }
}
				
			

The variable obj holds a String, but we try to cast it to an Integer. Since a String is not an Integer, the JVM throws the error.

Fix 1: Use instanceof to check the type first

				
					Object obj = "Hello";
if (obj instanceof Integer) {
    Integer num = (Integer) obj;
    System.out.println(num);
} else {
    System.out.println("Object is not an Integer");
}
				
			

The instanceof operator tells you the real type of the object before you try to cast.

Fix 2: Use pattern matching (Java 16 and above)

Newer versions of Java let you check and cast in one step.

				
					Object obj = "Hello";
if (obj instanceof String s) {
    System.out.println("Length is: " + s.length());
}
				
			

Fix 3: Use generics to avoid casting altogether

If you are working with collections like ArrayList, always use generics. They lock in the type at compile time so you never need to cast.

				
					// Bad: raw type, will need casting
List rawList = new ArrayList();
rawList.add("Hello");
String s = (String) rawList.get(0); // Risky

// Good: generic type, no casting needed
List<String> safeList = new ArrayList<>();
safeList.add("Hello");
String safe = safeList.get(0); // No cast, no risk
				
			

Generics are one of the easiest ways to write safer Java code as a student. Get in the habit of using them on day one.

ConcurrentModificationException

This scary-sounding error pops up when you change the structure of a collection (like an ArrayList or HashSet) while you are looping through it. Java does not let you add or remove items from a collection during iteration, because it confuses the iterator about the collection’s size.

Code Example:

				
					import java.util.*;
public class ConcurrentExample {
    public static void main(String[] args) {
        List<String> langs = new ArrayList<>(Arrays.asList("Java", "Python", "C++"));
        for (String l : langs) {
            if (l.startsWith("J")) {
                langs.remove(l); // ConcurrentModificationException
            }
        }
    }
}
				
			

The for-each loop is reading the list at the same time we are removing items from it. Java spots this and throws the error to stop a worse bug from happening.

Common causes:

  • Removing items from a list inside a for-each loop
  • Adding new items to the list during iteration
  • Changing the list without going through an iterator

Fix 1: Use the Iterator’s remove() method

When you need to remove items during iteration, use an Iterator and its remove() method.

				
					import java.util.*;

List<String> langs = new ArrayList<>(Arrays.asList("Java", "Python", "C++"));
Iterator<String> it = langs.iterator();

while (it.hasNext()) {
    String l = it.next();
    if (l.startsWith("J")) {
        it.remove(); // Safe removal
    }
}
System.out.println(langs); // [Python, C++]
				
			

The iterator knows it is removing an element, so it adjusts the count properly.

Fix 2: Make changes on a separate copy

Loop through the original list, but make changes on a copy.

				
					List<Integer> nums = new ArrayList<>(Arrays.asList(10, 20, 30));
List<Integer> copy = new ArrayList<>(nums);

for (int n : nums) {
    if (n == 20) {
        copy.add(40);
    }
}
System.out.println(copy); // [10, 20, 30, 40]
				
			

Fix 3: Use CopyOnWriteArrayList for thread-safe code

Java has a special list type called CopyOnWriteArrayList that allows safe changes during iteration. It is mostly used in multi-threaded code, but it works here too.

				
					import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

List<String> code = new CopyOnWriteArrayList<>(Arrays.asList("Coding", "Zap", "One"));
for (String c : code) {
    if (c.equals("One")) {
        code.remove(c); // Safe with CopyOnWriteArrayList
    }
}
System.out.println(code);
				
			

This list keeps a separate snapshot for the iterator, so changes do not break the loop. The trade-off is that it is slower than ArrayList, so use it only when you really need it.

StackOverflowError

This error is a favorite of recursion problems. A StackOverflowError happens when your program’s call stack runs out of memory. The call stack is where Java keeps track of every method that has been called but has not finished yet. When you have a recursive method that never stops, the stack keeps growing until it overflows.

Code Example:

				
					public class StackExample {
    public static int factorial(int n) {
        return n * factorial(n - 1); // No base case, runs forever
    }
    public static void main(String[] args) {
        factorial(5); // StackOverflowError
    }
}
				
			

The factorial method calls itself with no end in sight. After a few thousand calls, the stack fills up and the JVM crashes.

Common causes:

  • Missing a base case in a recursive method
  • Writing a base case that never gets reached
  • Two methods that call each other in a loop (mutual recursion with no exit)

Fix 1: Add a base case

Every recursive method needs a clear stopping point. For factorial, that point is when n reaches 0 or 1.

				
					public static int factorial(int n) {
    if (n == 0) {
        return 1; // Base case stops the recursion
    }
    return n * factorial(n - 1);
}
				
			

Now when n hits 0, the method returns a real number instead of calling itself again.

Fix 2: Use print statements to trace the recursion

When you cannot tell why your recursion is not stopping, add a print line at the top of the method.

				
					public static int factorial(int n) {
    System.out.println("factorial called with: " + n);
    if (n == 0) return 1;
    return n * factorial(n - 1);
}
				
			

If you see numbers going negative or never reaching the base case, you know your logic is off.

Fix 3: Read the stack trace

The error message Java prints shows you the exact line where the recursion is looping. Look at the top of the stack trace and check the base case in that method first.

Fix 4: Increase the stack size (last resort)

If your recursion is correct but just very deep, you can give the JVM more stack space with a command line flag:

				
					java -Xss2m YourProgram
				
			

This sets the stack size to 2 megabytes per thread. Use this only after you have made sure your base case is right. Bigger stack size does not fix bad code, it only delays the crash.

ArithmeticException

The ArithmeticException is thrown when something goes wrong in a math operation. The most famous trigger is dividing by zero with integers.

Code Example:

				
					public class MathExample {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int result = a / b; // ArithmeticException: / by zero
        System.out.println(result);
    }
}
				
			

When Java sees 10 / 0 with integers, it throws the error immediately.

One interesting note: this only happens with integer division. If you divide a double by zero, Java gives you Infinity or NaN instead of an error.

				
					double a = 10.0;
double b = 0.0;
System.out.println(a / b); // Prints Infinity, no error
				
			

Fix 1: Check the divisor before dividing

				
					int a = 10;
int b = 0;
if (b != 0) {
    System.out.println(a / b);
} else {
    System.out.println("Cannot divide by zero");
}
				
			

Fix 2: Use try-catch

				
					try {
    int result = a / b;
    System.out.println(result);
} catch (ArithmeticException e) {
    System.out.println("Math error: " + e.getMessage());
}
				
			

The fix is almost always to validate the input before doing the math. Trust no number that comes from outside your method.

How to Debug Java Errors Step by Step

Knowing the errors is half the battle. The other half is having a steady method to track them down when they show up. Here is a step-by-step process you can follow every time your code breaks.

Step 1: Read the error message carefully

The very first thing Java prints when something breaks is gold. It tells you the name of the error (like NullPointerException), a short message about what went wrong, and the line number where it happened. Most students glance at the error and panic. Slow down. Read it twice.

Step 2: Look at the stack trace

Below the error message, Java prints a list of method calls that led to the crash. This is called the stack trace. The top line is where the error actually happened. The lines below show how the program got there. Start at the top and work down.

Step 3: Open the file and find the line

Jump to the line number in your code. Look at the variables on that line. Ask yourself: which one could be null, which index could be out of range, which value could be wrong? Most of the time, the answer is right there.

Step 4: Use print statements

When the error is not obvious, add print statements before the broken line. Print the values of every variable. This often reveals that a variable holds something you did not expect.

				
					System.out.println("name = [" + name + "]");
System.out.println("index = " + index);
System.out.println("list size = " + list.size());
				
			

The square brackets help you spot hidden spaces or empty strings.

Step 5: Use a debugger

Every Java IDE (IntelliJ, Eclipse, VS Code) has a built-in debugger. Set a breakpoint on the broken line, run the program in debug mode, and inspect every variable at that exact moment. This is much faster than print statements once you get the hang of it.

Step 6: Search the error message

If you are still stuck, copy the error name and a key part of the message, then paste it into Google or Stack Overflow. Other students and pros have hit the same problem, and you will almost always find an answer in the first three results.

Step 7: Reduce the code to the smallest version that breaks

If your program is big, copy the broken section into a tiny new test program. Sometimes the act of cutting away unrelated code makes the bug obvious.

Following these steps in order will save you hours every week. Most experienced coders use the same routine.

Best Practices to Prevent Java Errors

Catching errors is good. Avoiding them in the first place is better. Here are habits that will keep most of these errors out of your code from the start.

Initialize variables when you declare them. Do not leave object variables as null if you can give them a real value right away. This kills most NullPointerException issues before they happen.

Always use generics with collections. Write List<String> instead of List. The compiler will catch type mistakes early and you will never need to cast.

Use try-catch around risky code. Anything that takes outside input, opens a file, or parses data should be inside a try-catch block. Even a simple log message in the catch helps you spot bugs faster.

Check array and list bounds. Before you use an index, make sure it is between 0 and length - 1. A two-second check saves a long debugging session.

Write base cases first in recursion. When you start a recursive method, type the base case before the recursive call. That way you can never forget it.

Use meaningful variable names. A variable called userInputString is clearer than s. Good names make errors easier to spot during code review.

Test with edge cases. Run your code with empty strings, zero values, negative numbers, and null inputs. If it breaks on these, fix it before submitting.

Keep methods short. A method that does one thing in 10 lines is easier to debug than one that does five things in 100 lines.

Use final for values that should not change. Marking a variable as final tells the compiler (and other readers) that it should not be reassigned.

Building these habits early makes coding more fun, because you spend less time stuck on red error messages and more time building things that work.

Frequently Asked Questions

1. What is the most common Java error for beginners?

The NullPointerException is by far the most common Java error students face. It happens when you call a method on an object that has not been given a value yet. Always check if an object is null before using it.

2. What is the difference between a Java error and a Java exception?

An Error in Java usually means something serious went wrong with the JVM itself, like running out of memory or stack space. An Exception is a problem in your code that you can usually catch and recover from. StackOverflowError is an Error, while NullPointerException is an Exception.

3. How do I find the line where my Java error happened?

Look at the stack trace that Java prints. The top line shows the file name and the exact line number where the error was thrown. Open that file, jump to that line, and start checking the variables there.

4. Can I prevent NullPointerException without if checks everywhere?

Yes. Use the Optional class from Java 8, or annotations like @NonNull from libraries like Lombok. You can also follow the rule of never returning null from your own methods. Return an empty list or a default value instead.

5. Why does my code work in IntelliJ but fail at runtime?

This usually means you have a runtime error, not a compile-time one. The compiler is happy with your syntax, but the actual values during execution cause problems. Check your inputs, null states, and array sizes.

6. What does “Exception in thread main” mean?

It means an uncaught exception was thrown inside your main method and stopped the program. Read the rest of the message to find out which type of exception and which line caused it.

7. Should I always use try-catch in my Java code?

Use try-catch around code that touches the outside world, like user input, files, network calls, or parsing. For your own internal logic, fixing the root cause is better than wrapping everything in try-catch.

8. How do I fix StackOverflowError in recursion?

Make sure your recursive method has a base case that actually gets reached. Then check that each recursive call moves toward that base case. If both look right and you still get the error, your recursion is just too deep, and you may need to switch to a loop.

9. Why does Integer.parseInt throw NumberFormatException?

It throws this error when the String you pass in is not a valid number. Common causes are extra spaces, letters mixed in, empty strings, or null. Always trim the String first and wrap the call in a try-catch block.

10. What is ConcurrentModificationException and how do I avoid it?

This error happens when you change a collection while looping through it. To avoid it, use the Iterator’s remove() method, work with a copy of the list, or use a CopyOnWriteArrayList.

Stuck on a Java assignment with errors you cannot fix?

Our tutors have helped thousands of students debug their Java homework and understand the why behind every error. Whether you are battling a stubborn NullPointerException or your recursion just will not stop, we can walk you through it step by step.

Check out our Live Java Tutoring services to get one-on-one support from real coders who teach in plain English.