Fundamentals 13 min read

6 Common Java Pitfalls Every Developer Should Avoid

This article walks Java developers through six frequent pitfalls—including misuse of the == operator, subtle bugs in Objects.equals, precision issues with BigDecimal, unexpected Stream filter behavior, autoboxing/unboxing surprises, and string replace quirks—offering clear explanations, code examples, and best‑practice solutions to help avoid costly bugs.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
6 Common Java Pitfalls Every Developer Should Avoid

1. Misusing the == operator

Comparing two Integer objects with == checks reference equality, not value equality, so new Integer(1) == new Integer(1) returns false. Use equals or Integer.valueOf for reliable value comparison.

Integer orderStatus1 = new Integer(1);
Integer orderStatus2 = new Integer(1);
System.out.println(orderStatus1 == orderStatus2); // false

When using Integer.valueOf, the cached range (-128 to 127) is applied, and the comparison may return true for values within that range.

String orderStatus1 = new String("1");
String orderStatus2 = new String("1");
System.out.println(Integer.valueOf(orderStatus1) == Integer.valueOf(orderStatus2)); // true

Prefer equals for object value comparison:

Integer orderStatus1 = new Integer(1);
Integer orderStatus2 = new Integer(1);
System.out.println(orderStatus1.equals(orderStatus2)); // true

2. Traps in Objects.equals

Using Objects.equals(userInfo.getId(), 888L) can fail because Integer.equals only returns true when the argument is also an Integer. Comparing an Integer with a Long always yields false.

if (Objects.equals(userInfo.getId(), 888L)) {
    sendEmail(userInfo);
}

Common mismatches include Long vs. Integer, Byte vs. Integer, and Double vs. Integer comparisons.

3. BigDecimal precision pitfalls

Creating a BigDecimal with a double constructor inherits the double's binary representation error, e.g., new BigDecimal(0.02) yields an imprecise value.

BigDecimal amount1 = new BigDecimal(0.02);
BigDecimal amount2 = new BigDecimal(0.03);
System.out.println(amount2.subtract(amount1)); // 0.0099999999999999984734433411404097569175064563751220703125

To avoid loss of precision, construct BigDecimal from a String or use BigDecimal.valueOf:

BigDecimal amount1 = new BigDecimal(Double.toString(0.02));
BigDecimal amount2 = new BigDecimal(Double.toString(0.03));
System.out.println(amount2.subtract(amount1)); // 0.01

// or
BigDecimal amount1 = BigDecimal.valueOf(0.02);
BigDecimal amount2 = BigDecimal.valueOf(0.03);
System.out.println(amount2.subtract(amount1)); // 0.01

4. Java 8 Stream filter pitfalls

Filtering a collection with stream().filter(...) returns a view that holds references to the original objects. Modifying an element in the filtered list also changes the element in the original list because both lists share the same object instances.

List<User> filterList = filterUser(userList);
for (User user : filterList) {
    user.setName(user.getName() + "Test");
}
// The names in userList are also changed.

5. Autoboxing/unboxing pitfalls

Automatic unboxing of a null wrapper type triggers a NullPointerException. For example, passing null as an Integer argument to a method expecting int causes the JVM to call intValue() on a null reference.

public static void main(String[] args) {
    Integer a = new Integer(1);
    Integer b = null;
    System.out.println(add(a, b)); // NPE
}

private static Integer add(int a, int b) {
    return a + b;
}

6. String replace pitfalls

The String.replace method replaces every occurrence of a character or CharSequence without requiring regex escaping, while replaceAll expects a regular expression. Using the wrong overload (e.g., escaping a literal asterisk in replace) prevents the replacement.

source.replace('A', 'B'); // replaces all 'A'
source.replace("A", "B"); // replaces all "A"
source.replaceAll("A", "B"); // regex based, also replaces all "A"
source.replaceAll("\\*", "C"); // regex, replaces '*'
// Wrong usage:
source.replace("\\*", "C"); // does not replace

To replace only the first match, use replaceFirst with a regex.

source.replaceFirst("A", "B");
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBigDecimalStreamsAutoboxingequalitycommon pitfallsString replace
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.