Top Mistakes of Beginner Java Developers: Advanced Level

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Top Mistakes of Beginner Java Developers: Advanced Level



Many developers, having mastered the basics of Java, move on to writing more complex code but continue to make typical mistakes that reduce application performance and reliability. In this article, we will analyze the top mistakes at an advanced level that Java developers encounter and show how to avoid them. The article will be useful for those who are already familiar with the language syntax but want to deepen their knowledge.



1. Incorrect Use of Optional



The Optional class was introduced in Java 8 to combat NullPointerException. However, many developers use it incorrectly, turning an elegant solution into a source of new problems.



Mistake: Using Optional.get() Without Checking



One of the most common mistakes is calling the get() method without first checking isPresent(). This leads to a NoSuchElementException.



// IncorrectOptional<String> name = Optional.ofNullable(getName());String result = name.get(); // Exception if name == null

// CorrectString result = name.orElse("Default");// Or with handlingname.ifPresent(System.out::println);


Mistake: Using Optional in Class Fields



Optional is not intended for use as class fields or method parameters. This breaks serialization and adds unnecessary complexity.



// Incorrectpublic class User {    private Optional<String> email; // Not serializable}

// Correctpublic class User { private String email; // null means absence}


Mistake: Chaining Optional.orElse() with Expensive Computations



The orElse() method always evaluates its argument, even if the value is present. Use orElseGet() for lazy evaluation.



// Incorrect — expensiveCall() is always executedString result = optional.orElse(expensiveCall());

// Correct — expensiveCall() is executed only when value is absentString result = optional.orElseGet(() -> expensiveCall());


2. Memory Leaks and Incorrect Work with Collections



Advanced developers often encounter memory leaks that are difficult to detect. Let's look at the main causes.



Mistake: Forgetting to Override equals() and hashCode()



When using objects in HashMap or HashSet without correct equals() and hashCode(), objects are not removed from the collection, leading to leaks.



public class Key {    private int id;        // Forgot to override equals() and hashCode()    // Now keys are considered different, even if id matches}

Map<Key, String> map = new HashMap<>();map.put(new Key(1), "value");map.get(new Key(1)); // null — memory leak


Mistake: Storing Large Objects in Static Collections



Static collections live until the application ends. If data is added to them without control, this will lead to OutOfMemoryError.



// Bad practicepublic class CacheManager {    private static List<byte[]> cache = new ArrayList<>();        public static void addData(byte[] data) {        cache.add(data); // Grows indefinitely    }}

// Solution: use WeakHashMap or limit the sizeprivate static Map<String, byte[]> cache = new WeakHashMap<>();


Mistake: Closing Resources via finalize()



The finalize() method is deprecated and unreliable. Use try-with-resources for automatic closing.



// Incorrectpublic class Resource {    @Override    protected void finalize() throws Throwable {        // Closing resource — may not be called                

Blogs

Book Recommendations