15 + 11 Mistakes Every Java Developer MUST avoid TODAY

Varsha Das
Level Up Coding
Published in
7 min readApr 30, 2024

--

Do you want to be your code reviewer’s favorite developer?

Do you dream of getting your pull requests merged with minimal change requests?

Do you also want to be known as a pro-code reviewer?

..

..

..

Then you are at the right place!

You must be wondering, Why should you care?

To answer that, I would like to say that, mastering these do’s and don’ts while writing code isn’t just about impressing your peers (though that’s a nice bonus). It’s about writing code that’s easier to understand, maintain, and extend. It’s about saving time and effort in the long run by preemptively addressing potential issues.

Photo by True Agency on Unsplash

In this article, you will learn about the top 11 clean code practices — good vs bad—that every Java developer should master.

But that’s not all. Along with these fundamental practices, we have also created a YouTube video for you covering 15 common mistakes to avoid while coding in Java. You can find the video link below, and I highly recommend watching it before diving into this article to ensure your concepts are thoroughly understood.

So, let’s get started!

1. Nulls and Optionals

Bad Practice: Returning null from a method can lead to the most dreaded NullPointerExceptions, or NPEs.

Good Practice: Using Optional allows for a more explicit handling of null and prevents such errors.

2. Optimal String Conversion with String.valueOf()

Bad Practice: Using + operator for string concatenation.

  • Here, the ‘+’ operator is used for string conversion, which involves implicit string concatenation.
  • This approach can be inefficient, especially when converting large numbers of variables to strings.

Good Practice: Using built-in methods for string concatenation.

  • Here, we are using valueOf(), for string conversion and concatenation.
  • This method is specifically designed for converting other data types to strings and is optimized for performance.

3. Use Arrays.copyOf( ) for copying array

Bad Practice: Manually copying arrays

  • This approach is less efficient, especially for large arrays, as it involves multiple iterations and element assignments.

Good Practice: Using Arrays.copyOf() to copy arrays

4. Use isEmpty() for Checking Empty Collections

Bad Practice: Using length() or size() to check if a string or collection is empty.

  • Here, length() is used to check if a string is empty, and size() is used to check if a set is empty.
  • These methods work but they make the code less readable.

Good Practice: Using isEmpty() to check if a string or collection is empty.

  • isEmpty() method can be used for both string and set to check for emptiness.
  • It has a time complexity of O(1), making it more efficient and readable.

5. Avoid Concurrent Modification Exception

Bad Practice: Removing elements from the list while iterating through it leads to a ConcurrentModificationException.

Output:

Good Practice: Using iterator’s remove method or removeIf() method

List<String> words = new ArrayList<>();
words.add("A");
words.add("B");
words.add("C");

Iterator<String> iterator = words.iterator();
while (iterator.hasNext()) {
String word = iterator.next();
if (word.equals("A")) {
iterator.remove(); // Use iterator's remove method to safely remove elements
}
}

System.out.println(words); // Output: [B, C]

One very important thing to note:

  • The iterator itself is fail-fast, meaning it will detect concurrent modifications and throw an exception if the underlying collection is modified directly during iteration.
  • However, the remove() method provided by the iterator implementation is fail-safe, allowing elements to be safely removed from the collection while iterating over it without throwing a ConcurrentModificationException.

We use the iterator’s remove() method to safely remove elements from the list words during iteration.

List<String> words = new ArrayList<>();
words.add("A");
words.add("B");
words.add("C");

words.removeIf(word -> word.equals("A")); // Use removeIf method to remove elements matching the condition

System.out.println(words); // Output: [B, C]

We use the removeIf() method introduced in Java 8 to remove elements from the list words based on a given condition. This method internally uses an iterator and removes elements matching the condition. It's a more concise and readable way to remove elements that meet a specific criterion from the collection.

6. Precompile Regular Expressions

Bad Practice: Compiling regular expressions at runtime

  • Here, regular expressions are compiled at runtime whenever they are used.
  • When same regular expressions are used repeatedly, it will degrade the performance.

Good Practice: Precompiling and reusing regular expressions

  • By precompiling repeated regular expressions and then reusing it wherever required, we can avoid redundant compilation and improve performance.

7. Avoid Pre-checking Data Existence Before Retrieval

Bad Practice:

  • Here, we first check if the id exists in the map before retrieving it.
  • This pre-checking is unnecessary because the get method of a map returns null if the key is not found.

Good Practice:

  • Here, we directly retrieve the id from the map using the get method and then check if the role is not null.
  • This approach avoids redundant checks and leads to cleaner and more efficient code.

8. Efficient Conversion of Collection to Array

Bad Practice:

  • In this approach, the size of the list is first calculated and then a new array is created.
  • This can impact performance, especially for large collections.

Good Practice:

  • Here, toArray is called with an empty array (new String[0]).
  • This approach avoids the need to calculate the size of the list and allows the toArray method to handle the array resizing internally, leading to better performance and cleaner code.

9. Using Default Methods

Bad Practice:

  • If a new method, such as logError, needs to be added to the interface, all implementing classes must be modified, which could lead to code maintenance issues and potential errors.

Good Practice:

  • Here, the Logger interface defines a default method(logError), which provides a default implementation for logging errors. Implementing classes automatically inherit this default implementation without the need for modifications.

10. Using Date/Time API

Bad Practice: Using legacy Date class

  • This class has various issues, like mutability and lack of clarity in its methods.
  • Most of the methods in this class, like getYear(), getMonth(), and getDay() are deprecated.

Good Practice: Using classes from the Date/Time API(Java 8 onwards)

  • Here, we use LocalDate class from the Date/Time API.
  • LocalDate is immutable, ensuring thread safety, and provides clear and intuitive methods for date manipulation.

11. Forgetting to use Generics

Bad Practice:

ArrayList list = new ArrayList();
list.add(10);
list.add("Hello");

Different data types are mixed in the list, which can lead to runtime errors.

Good Practice: Using generics ensures type safety and prevents such issues.

ArrayList<Integer> list = new ArrayList<>();
list.add(10);
// list.add("Hello"); // Compile-time error: incompatible types

Well, congratulations if you have made it to the end of this article.

Thanks for reading.

If you liked this article, please click the “clap” button 👏 a few times.

It gives me enough motivation to put out more content like this. Please share it with a friend who you think this article might help.

Connect with me — Varsha Das | LinkedIn

If you’re seeking personalized guidance in software engineering, career development, core Java, Systems design, or interview preparation, let’s connect here.

Rest assured, I’m not just committed; I pour my heart and soul into every interaction. I have a genuine passion for decoding complex problems, offering customised solutions, and connecting with individuals from diverse backgrounds.

Follow my Youtube channel — Code With Ease — By Varsha, where we discuss Java & Data Structures & Algorithms and so much more.

Subscribe here to receive alerts whenever I publish an article.

Happy learning and growing together.

--

--

"Senior Software Engineer @Fintech | Digital Creator @Youtube | Thrive on daily excellence | ❤️ complexity -> clarity | Devoted to health and continuous growth