5 Best and Worst Practices in Java Coding

by Tosho Trajanov

7 min read

Are you a junior Java developer who wants to land his first job? Are you eager to discover how you can develop sophisticated solutions with your team?

You're in luck!

This post contains the top 5 best practices when coding in Java, as well as the most common mistakes Java developers make in their daily coding activities.

Let's begin!

5 Best Practices When Coding in Java

As a Java developer, these are some of the best practices you should try out while writing codes for your next projects:

  • Using Naming Conventions
  • Ordering Class Members by Scopes
  • Class Members should be private
  • Using Underscores in Numeric Literals
  • Avoid Redundant Initialization (0-false-null)

Using Naming Conventions

You must be intentional in how you handle the naming convention for your codes and this is even what you do before starting to write a single line of code.

For instance, using naming conventions cover everything that has to do with rightfully naming a variable, constant, method, class and interface, etc. 

When naming identifiers (methods, classes, and variables), it's a good practice for you to let the respective things you name them with to be self-explanatory, distinct, and pronounceable.

Most importantly, you must always ensure to write readable codes that are easily understood by humans (and not just write codes for the sake of satisfying the compiler). 

Ordering Class Members by Scopes

Organizing member variables of a class through their scopes is another good coding practice you should always try to implement while coding.

That’s to say that, as a Java developer, it would be nice of you to sort each member by the visibility of the access modifiers: private, default (package), protected, and public. And a blank line separates each of the groups. 

Class Members Should Be Private

It's a good coding practice in Java programming to try as much as possible to reduce the accessibility of class members to the barest minimum possible.

When trying to protect the class members, you should make use of the least possible access modifier. 

Why is it highly recommended to make class members (identifiers) private?

The only logical reason for practicing this is to bring out the usefulness of encapsulating information in software development. 

Using Underscores in Numeric Literals 

You can now write lengthy numeric literals that have a great readability score many thanks to the update done in Java 7. 

Before using Underscore:

int minUploadSize = 05437326;
long debitBalance = 5000000000000000L;
float pi = 3.141592653589F;

After making use of Underscore:

int minUploadSize = 05_437_326;
long debitBalance = 5_000_000_000_000_000L;
float pi = 3.141_592_653_589F;

The above-written declarations in Java show the importance of using underscores in numeric literals to improve the readability of codes. When you compare the two declarations above, you would be able to deduce that the one with included underscores is more readable compared to the other one. 

Avoid Redundant Initialization (0-false-null)

As a developer, you should always avoid initializing member variables with values such as null, false, and 0. In Java, you don't necessarily need to do this because these values are the default initialization values of member variables. 

For example, the initialization done below is not needed hence it is redundant: 

public class Person {
   string name = null;
   private int age = 0;
   private boolean isGenius = false;
}

5 Worst Practices When Coding in Java

These are some of the worst practices you should try as much as possible to avoid while you write code for your next project:

  • Neglecting Existing Libraries
  • Using Raw Type Instead of a Parameterized One
  • Ignoring Exceptions
  • Excessive Garbage Allocation
  • Forgetting to Free Resources

Neglecting Existing Libraries 

It’s not a good idea to always neglect numerous amounts of libraries written in Java. It’s always advisable for anyone in this regard to try and search for available libraries before getting too deep with a task (project). 

What makes these existing libraries special?

A lot of these particular libraries have been reworked on and improved over the years. That's not all, they are also free to use. These existing libraries could come in form of network-related libraries (such as Akka, Netty, etc.) or logging libraries (such as Log4j, logback, etc.) 

Using Raw Type Instead of a Parameterized One

In general, Raw Types are either not parametrized, or non-static members of class R that are not inherited from the superclass or superinterface of R. Not until generic types were introduced in Java, raw types never had an alternative. 

Though raw types have had support for generic programming since version 15 an inadequacy has been discovered to possibly breakdown the system as a result of backward compatibility reasons. 

List listOfNumbers = new ArrayList();
listOfNumbers.add(20);
listOfNumbers.add("Forty");
listOfNumbers.forEach(n -> System.out.println((int) n * 2));

For instance, in the above lines of codes, we defined a list of numbers as a raw “ArrayList". Any object can be added to it since the type of the "ArrayList" wasn't specified with the type parameter. 

If you check the last line in the above codes, you will see that we cast elements to int, double it, and print the doubled number to standard output. The truth is that there won’t be errors in it during compilation time but during runtime the reason because we tried to cast a string to an integer.

How can this be corrected?

The only way out is by defining the collection by specifying the type of data getting stored in the collection. The lines of codes below show that:

List<Integer> listOfNumbers = new ArrayList<>();
listOfNumbers.add(20);
listOfNumbers.add("Forty");
listOfNumbers.forEach(n -> System.out.println((int) n * 2));

Nevertheless, the above-corrected version won't compile well because we tried to add a string into a collection that is expected to store integers only. Where we tried to add the string “Forty”, the compiler will show and point at an error. 

Above all, parameterizing generic types is the best way out of this. By this, the compiler can see and make all the possible types hence reducing the chances of runtime exceptions. 

Ignoring Exceptions

Leaving exceptions unhandled might be tempting but always try as much as possible to handle them. Addressing these exceptions when they appear is the only way out of this because they are intentionally thrown. 

But how do you address them?

Either by:

  • rethrowing them.
  • showing an error dialog to the user.
  • adding a message to the log.

At least it’s better to let other developers know the reason behind leaving out the exceptions. 

By encoding:

“try { selfie.delete(); } catch (NullPointerException unimportant) {  }” 

into the exceptions’ variable name is one of the best ways of highlighting an exception’s importance. 

Excessive Garbage Allocation

Creating many short-lived objects may result in excessive garbage allocation. This is never a good practice in Java programming because the performance of an application is affected negatively anytime the garbage collector tries to remove an unneeded object from memory.

 StringBuilder oneMillionHelloSB = new StringBuilder();
    for (int i = 0; i < 1000000; i++) {
        oneMillionHelloSB.append("Hello!");
    }
System.out.println(oneMillionHelloSB.toString().substring(0, 6));

Strings are immutable in so that is why we used a mutable StringBuilder in the above example so that our code will execute very fast within a second. 

Forgetting to Free Resources

You should always try to free resources any time they are done using them. Also, similar caution needs to be taken any time an exception is thrown during an operation on such particular resources too. 

Conclusion

In this tutorial, we've explored the best and worst practices when coding in Java. We say how organizing member variables of a class through their scopes is a great coding practice you should always try to implement while coding.

We also saw how leaving exceptions unhandled might be tempting but it a practice we should avoid as much as possible.

All in all, all of the practices mentioned above lead to one thing: making our code cleaner and better.

On the plus side, a developer who constantly strives to improve stands a good chance to be contacted by a client looking to hire Java developers.

Good luck!

FAQs

Q: How to refactor legacy Java code to adhere to best practices?
Effectively refactor legacy Java code by identifying areas that violate best practices, breaking down the process into manageable tasks, gradually introducing improvements such as replacing deprecated methods, optimizing algorithms, and enhancing code readability with modern Java features. Implement automated testing to ensure behavior remains consistent.
Q: Strategies for teaching these best and worst practices to new Java developers?
Teach best and worst Java practices through code reviews, pair programming, interactive workshops focusing on practical examples, and encouraging participation in open-source projects. Use real-world scenarios to illustrate consequences and benefits.  
Q: Impact of these practices on software maintainability and scalability?
Adhering to best practices enhances software maintainability by making code easier to understand, debug, and extend. It improves scalability by ensuring that applications perform well and can be efficiently updated or expanded to meet growing demands.
Q: What does static mean in Java?
In Java, the keyword Static simply means that a particular member belongs to a type itself and not an instance of that type. In other words, it can be deduced that only an instance of that static member is created and shared across every instance of the class.
Q: What is Encapsulation in Java?
In Java, encapsulation is simply the wrapping of code and data together in a single unit.
Tosho Trajanov
Tosho Trajanov
Co-founder

Tosho is a co-founder at Adeva, with over a decade of experience in the tech industry. He has partnered with diverse organizations, from nimble startups to Fortune 500 companies, to drive technological advancements and champion the effectiveness of cross-cultural, distributed teams.

Expertise
  • Leadership
  • Planning
  • Product Strategy
  • Software Architecture
  • Agile Methodologies
  • AWS
  • Microservices
  • PHP
  • PHP 5
  • +4

Ready to start?

Get in touch or schedule a call.