Skip to content

Top Java Bugs and How to Fix Them

Java is a powerful and widely used programming language, but developers often encounter common pitfalls that can lead to bugs and performance issues. Understanding these bugs and their solutions can help improve code reliability and maintainability. Here are some of the most common Java bugs and how to fix them.

1. NullPointerException (NPE)

A NullPointerException occurs when trying to access a method or field of a null object.

Example Bug:

String text = null;

System.out.println(text.length());  // Throws NullPointerException

Fix:

Always check for null before accessing an object.

if (text != null) {

    System.out.println(text.length());

} else {

    System.out.println(“String is null”);

}

Alternatively, use Optional in Java 8+ to handle null values safely.

Optional.ofNullable(text).ifPresent(t -> System.out.println(t.length()));

2. Infinite Loops

Infinite loops occur when the termination condition is not met or improperly implemented.

Example Bug:

int i = 0;

while (i < 5) {

    System.out.println(i);

    // Missing i++ causes infinite loop

}

Fix:

Ensure the loop condition is properly updated.

int i = 0;

while (i < 5) {

    System.out.println(i);

    i++;  // Correctly incrementing i

}

3. ArrayIndexOutOfBoundsException

Trying to access an array element outside its valid range results in this exception.

Example Bug:

int[] numbers = {1, 2, 3};

System.out.println(numbers[3]);  // Throws ArrayIndexOutOfBoundsException

Fix:

Always check the array length before accessing an index.

if (index >= 0 && index < numbers.length) {

    System.out.println(numbers[index]);

} else {

    System.out.println(“Invalid index”);

}

4. Using == Instead of .equals() for String Comparison

The == operator checks object reference equality, not content equality.

Example Bug:

String s1 = “hello”;

String s2 = new String(“hello”);

System.out.println(s1 == s2);  // false (compares memory locations)

Fix:

Use .equals() to compare string values.

System.out.println(s1.equals(s2));  // true (compares content)

5. Memory Leaks from Unclosed Resources

Not closing resources like file streams or database connections can cause memory leaks.

Example Bug:

FileReader fr = new FileReader(“data.txt”);

// Forgot to close file

Fix:

Use try-with-resources (Java 7+), which automatically closes resources.

try (FileReader fr = new FileReader(“data.txt”)) {

    // Read file

} catch (IOException e) {

    e.printStackTrace();

}

6. Concurrent Modification Exception

Modifying a collection while iterating over it can cause a ConcurrentModificationException.

Example Bug:

List<String> list = new ArrayList<>();

list.add(“A”);

list.add(“B”);

for (String item : list) {

    if (item.equals(“A”)) {

        list.remove(item);  // Throws ConcurrentModificationException

    }

}

Fix:

Use an iterator’s remove() method instead.

Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {

    if (iterator.next().equals(“A”)) {

        iterator.remove();

    }

}

7. Forgetting to Override hashCode() When Overriding equals()

If hashCode() is not overridden when equals() is overridden, objects may not behave correctly in hash-based collections like HashSet or HashMap.

Example Bug:

class Person {

    String name;

    Person(String name) { this.name = name; }

    @Override

    public boolean equals(Object obj) {

        if (this == obj) return true;

        if (obj == null || getClass() != obj.getClass()) return false;

        Person person = (Person) obj;

        return Objects.equals(name, person.name);

    }

}

Set<Person> people = new HashSet<>();

people.add(new Person(“Alice”));

System.out.println(people.contains(new Person(“Alice”)));  // false (unexpected)

Fix:

Always override hashCode() when overriding equals().

@Override

public int hashCode() {

    return Objects.hash(name);

}

8. Ignoring Exceptions

Catching an exception but not handling it can lead to hidden issues.

Example Bug:

try {

    int result = 10 / 0;

} catch (ArithmeticException e) {

    // Silent catch, no error message

}

Fix:

Log the exception or handle it appropriately.

try {

    int result = 10 / 0;

} catch (ArithmeticException e) {

    System.out.println(“Error: ” + e.getMessage());

}

9. Deadlocks in Multithreading

A deadlock occurs when two threads wait indefinitely for each other to release a lock.

Example Bug:

class Deadlock {

    static final Object lock1 = new Object();

    static final Object lock2 = new Object();

    public static void main(String[] args) {

        new Thread(() -> {

            synchronized (lock1) {

                synchronized (lock2) {  // Locks in one order

                    System.out.println(“Thread 1”);

                }

            }

        }).start();

        new Thread(() -> {

            synchronized (lock2) {

                synchronized (lock1) {  // Locks in reverse order

                    System.out.println(“Thread 2”);

                }

            }

        }).start();

    }

}

Fix:

Always acquire locks in a consistent order to prevent deadlocks.

synchronized (lock1) {

    synchronized (lock2) {

        System.out.println(“Thread Safe”);

    }

}

10. Overlooking Integer Division Precision

Integer division in Java discards the decimal part, leading to incorrect results.

Example Bug:

int a = 5, b = 2;

System.out.println(a / b);  // Outputs 2 instead of 2.5

Fix:

Use double for division.

double result = (double) a / b;

System.out.println(result);  // Outputs 2.5

Conclusion

Java bugs often stem from common mistakes in handling null values, collections, multithreading, and resource management. By understanding these pitfalls and applying best practices, developers can write more robust, efficient, and maintainable Java applications.

Leave a Reply

Discover more from Sowft | Transforming Ideas into Digital Success

Subscribe now to keep reading and get access to the full archive.

Continue reading