Top Mistakes Java Developers Make - and How to Fix Them

JeniferJenifer
10 min read

Being one of the most promising and the most object-oriented programming languages developed by Oracle, Java has definitely been quite a talk of the town, mainly considered to develop a wide range of Android apps, web apps, gaming apps, and of course, several database-driven software.

One of the most erroneous beliefs that has been rising slowly is that we tend to pick up coding languages as we move on, but sadly, not all developers are able to consider this. And by the time they realize what’s happening around, chances are pretty high for the code to become more convoluted, unmanageable, and bugs start crawling out, resulting in unwanted repercussions.

Which is why it is highly emphasized on the fact that developers must read some interesting, informative articles or self-teach themselves on posts focusing on how Java works. Well, for now, you no longer have to go anywhere since the following article does the same. As the title suggests, the post focuses on some of the most common yet crucial mistakes that are spotted and must be avoided or fixed before something bigger happens later on.

What are the roles and responsibilities of a Java developer?

Much like any other developer, a Java developer’s role and responsibility is to design, develop as well and maintain different Java-based applications as well as systems. Right from writing code, debugging, establishing seamless collaboration with different teams, addressing troubleshooting issues, and above all, ensuring the final product meets user needs. And their jobs don’t end here, they are also asked to play a significant role in testing, quality assurance, and successful deployment.

Now it doesn’t matter whether you are just a beginner or an experienced one, errors are a pretty much inevitable part of any kind of development project. Fret not, there is a solution for every issue, and most of these below-mentioned mistakes can be easily avoided.

Top Common Java Development Mistakes to Take into Account

  1. Misusing mutable vs. immutable variables

One of the most common mistakes found is not striking a careful balance between developing a mutable or an immutable object. So what exactly are the two? A mutable object can be successfully modified after creation, whereas this is just not the case with immutable objects. And this is the reason why immutable objects end up offering a wide range of benefits such as great safety, simplicity, reduced memory, and a lot more. This is why garbage collection is successfully built up, especially when there is a requirement for a separate object for each distinct value. Some of the major key differences between mutable and immutable objects include:

Mutable 

Immutable 

Once the changes are made to the existing object, there is no possibility for any new object to be formed. 

Even if changes are made in an existing object, there is a high possibility for a new object to be formed. 

Several methods are offered to change the overall content of the object

Unfortunately, no methods are provided to change the content of the object 

Here, both getter and setter are available. 

Only getter methods are present here. There are no setter methods here. 

StringBuffer , StringBuilder, and java.util.date.

legacy classes, wrapper classes, and String classes.

  1. Not using “==” to compare different values

Another common Java error that should be spoken about is that developers end up using “=” instead of “==”; they usually do so to compare different values. Now you see, when you are conducting a development project, it doesn’t mean you should stick to working with a single tech program, multiple languages and technologies are used and this is where developers most of the time end up making such silly errors since “==” is not used in several other languages. Another reason that could lead to such issues is a typing error.

As a solution, the compiler can detect it whenever you tend to use “=” instead of “==”, which is mainly used for assignment in Java. And what happens next is you will find an error stating “Can’t convert <data type1> to Boolean”. So the term <data type> here means a Java type which you are assigning to assist seamlessly instead of comparing them.

  1. Not using a static analysis tool

The next type of Java mistake is the static analysis tool. Yes, don’t get me wrong, the mistake lies in not using a static analysis tool. Before understanding why you need to use the tool in the first place, one must understand what the tool does. A static analysis tool mainly tends to inspect the source code for potential problems, and all this is possible without the need to run it. Fortunately, such tools can be considered for developing different systems, such as Maven or Gradle. This means that whatever the output is, it is seamlessly visible.

So these usually tend to operate on source code instead of compiled classes, professionals can look further for a wider range of problems and issues in comparison to what unit tests alone can offer.

  1. Writing blank exception handlers

Another common Java error made by amateur developers all across the globe is writing blank exception handlers. So, what usually happens when you leave the exception handlers blank? Of course, it does get the job of preventing the cash done and error messages can be skipped. So what’s the issue here? Well, the issue will arise as soon as you get to learn about the cause of the exception. Since you haven’t written any error messages, finding out where the exception has occurred is simply next to impossible.

So, how to deal with this? Well, try-catch exception around your code to catch in case the exception is thrown, and a simple message will be printed out. Moreover, you no longer have to write a custom handler for every exception.

public static void main(String args[])

{

try {

//code statements

}

catch (Exception e)

{

System.out.println ("Error Message "+e );

}

}

  1. Memory Leaks

The next common mistake to take into account is the memory leaks. This is a pretty well-known fact that Java mostly uses automatic memory management; it’s a great relief to forget about allocating and freeing all the memory manually; however, this doesn’t mean Java developers shouldn’t be aware of how memory is used in the development of the app. However, all this isn’t as swift and as smooth as it seems. As long as programs begin creating relevant references to the specific objects, especially the ones that are no longer required, they won’t be freed completely. In one way or the other, this still can be considered as a memory leak since it’s possible in a plethora of ways in Java development projects. One of the most common reasons this happens is everlasting object references. Since the garbage collector can’t remove objects from the heap even though there are a plethora of references, such as defining a class with a static field containing some collection of objects, and forgetting to set that static field to null after the collection is no longer needed. Static fields are considered GC roots and are never collected.

final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

final Deque<BigDecimal> numbers = new LinkedBlockingDeque<>();

final BigDecimal divisor = new BigDecimal(51);

scheduledExecutorService.scheduleAtFixedRate(() -> {

BigDecimal number = numbers.peekLast();

if (number != null && number.remainder(divisor).byteValue() == 0) {

System.out.println("Number: " + number);

System.out.println("Deque size: " + numbers.size());

}

}, 10, 10, TimeUnit.MILLISECONDS);

scheduledExecutorService.scheduleAtFixedRate(() -> {

numbers.add(new BigDecimal(System.currentTimeMillis()));

}, 10, 10, TimeUnit.MILLISECONDS);

try {

scheduledExecutorService.awaitTermination(1, TimeUnit.DAYS);

} catch (InterruptedException e) {

e.printStackTrace();

}

  1. An array always starts with the 0th index in Java

This is usually the case; in the Java realm, arrays and other objects are mainly zero-indexed, which means, in the literal sense, the first element is always zero.

//Creating a small array of 3 integers

String[] myArr = new int[3];

//Index of first element is 0, so,

myArr[0] = 1;

//Second index is actually 1

myArr[1] = 2;

//Final element's index will be 2

myArr[2] = 3;

So, in case you try accessing myArr [3], it means you are successfully willing to access the fourth element, instead of the third. So what does this lead to? ArrayOutOfBoundsException. I am sure you must have found a similar kind of error when dealing with strings, especially if you tend to go beyond the length; these are also zero-indexed. Now there are several other parts which are also zero-indexed, such as Java. util.Calendar class in which months also start with 0.

Now, this is not the same scenario for class, and keeping all these rules in mind can be pretty overwhelming. Fortunately, there are numerous documents available, especially if you are using a new class.

  1. Not using generics

Of course, generics turn out to be one of the most crucial features which added in Java 5, and no wonder it offers a wide range of advantages such as:

  • Type safety at compile time

  • No need to cast each element explicitly

  • No classcastexception at runtime

  • All elements are sorted in the correct order

  • List employees = new ArrayList();

  • // add employee objects to the list...

  • Employees.add("John"); // compiler allows this but throws exception at runtime.

  • Using raw types in new code

9. Using null references

Another major mistake that should be avoided at any cost is avoiding excessive use of null. It is highly preferable to return empty arrays or collections from different methods instead of using nulls, as this can assist well in preventing from NullPointerException.

List<String> accountIds = person.getAccountIds();

for (String accountId: accountIds) {

processAccount(accountId);

}

The NullPointerException will be raised if the person has no account. To fix all these things, it is very important to conduct a null-check. In case if it returns an empty list, then NullPointerException won’t be a concern at all. In case you want to completely avoid nulls, you can think of consider different strategies, such as using the Optional type, which can be an empty object or a wrapper of some value:

Optional<String> optionalString = Optional.ofNullable(nullableString);

if(optionalString.isPresent()) {

System.out.println(optionalString.get());

}

Here, take a look at Java 8, it offers:

Optional<String> optionalString = Optional.ofNullable(nullableString);

optionalString.ifPresent(System.out::println);

10. Ignoring exceptions

Last but certainly not least is not writing code for handling exceptions. Of course, on the surface, all this might seem completely fine, especially if the code is running without any exceptions, but what you might not know is, it can cause the code to fall silent.

To avoid making such a mistake, all you need to do is handle all the exceptions with Try-Catch-Finally. Now what this means is:

  • The first one is about enclosing the block, which might comprise an exception

  • The second one features one or more blocks that have the potential to handle exceptions

  • The third one is about executing the block successfully

FileInputStream input = null;

try{

File file = new File("./index.txt");

input = new FileInputStream(file);

} catch (FileNotFoundException e) {

e.printStackTrace();

finally {

if (input !=null) {

try {

inputStream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

}

So this is it! Mistakes are pretty inevitable, and all you need to do is keep practicing and finding the way out.

Conclusion

Java is one such platform that seems to have tremendous potential to simplify several things in the software development realm. No matter how much you are aware of what’s going on, issues won’t be lessened, especially with its relevant features such as removing manual memory management or decent OOP tools, and more. So, as the ultimate solution, try to increase your knowledge, keep practicing, take all the relevant Java tutorials into account, read JVM documentation, and of course, try writing as many programs as you can.

On and all, it is mainly about creating a strong foundation and staying absolutely curious and improvising now and then. Whether you have just kick-started your career as a developer or have been in the development scenario for a couple of years now, the key is to cultivate a mindset towards absolute excellence and innovation. So keep growing, keep making more and more mistakes, keep learning from them, and let your Java journey be an inspiring tale of progress and mastery!

I hope you did find the following post worth reading. In case you still have any doubts or queries, feel free to mention them in the comment section below. We will reach out to you as soon as we can.

0
Subscribe to my newsletter

Read articles from Jenifer directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jenifer
Jenifer