Common Mistakes
Every Java developer runs into the same handful of gotchas at some point — most of them don’t cause a compile error, they cause a confusing bug or crash later, often far away from the line that actually caused it. Recognizing them ahead of time saves hours of debugging.
Mistake | Why it bites | What to do instead |
|---|---|---|
Using |
| Use |
Overriding | Breaks the equals/hashCode contract, so equal objects can land in different hash buckets — | Always override both together (or generate both with your IDE, or use a |
Mutable | A | Prefer instance fields; if state truly must be shared, make it immutable or explicitly manage synchronization. |
Catching | Swallows bugs you never intended to handle — a | Catch the narrowest exception type that describes what you can actually recover from. |
Not closing resources (pre-try-with-resources style) | Forgetting to close a file, socket, or DB connection in a | Use try-with-resources for anything |
NullPointerException from an unboxed wrapper | Autoboxing quietly unboxes | Be deliberate about where |
Modifying a collection while iterating over it | Calling | Use |
Comparing floating-point numbers with |
| Compare with a tolerance: |
== vs. equals(), in code
A classic surprise with String literals vs. new String()
String a = "hello";
String b = "hello";
String c = new String("hello");
System.out.println(a == b); // true — same interned literal
System.out.println(a == c); // false — c is a distinct object
System.out.println(a.equals(c)); // true — same contentConcurrentModificationException, in code
Wrong: mutating a list during a for-each
List<String> names = new ArrayList<>(List.of("Alice", "Bob", "Carol"));
for (String name : names) {
if (name.startsWith("B")) {
names.remove(name); // throws ConcurrentModificationException
}
}Right: removeIf(), or an explicit Iterator
names.removeIf(name -> name.startsWith("B"));
// or, with explicit control over the iteration:
Iterator<String> it = names.iterator();
while (it.hasNext()) {
if (it.next().startsWith("B")) {
it.remove(); // safe — goes through the iterator itself
}
}NullPointerException from unboxing
A null wrapper blowing up on unboxing
Map<String, Integer> scores = new HashMap<>();
int score = scores.get("Alice"); // scores.get returns null (key missing)
// NullPointerException — Java tries to unbox null into an int