Is your Java code really production-ready?
Tags: java
Published: 2019-09-23 16:07:08

---
title: Is your Java code really production-ready?
published: true
description: Prevent bugs in complex, shared Java applications with these simple tips.
tags: java
cover_image: https://thepracticaldev.s3.amazonaws.com/i/qedd8xqzhivh7i0565cx.png
---

Is your Java really ready for prime time in production?

Here are five tips for writing Java that can withstand the abuses of your users!

![Duke, the Java mascot, rocking out](https://thepracticaldev.s3.amazonaws.com/i/s7m43b5nejlbhdlkzh1m.jpg)

## Write dumb code

My article [Why Senior Devs Write Dumb Code and How to Spot a Junior From A Mile Away](https://medium.com/hackernoon/why-senior-devs-write-dumb-code-and-how-to-spot-a-junior-from-a-mile-away-27fa263b101a) is still shared often on Twitter even though its almost two years old. The advice to write dumb code isn't mine, it's Java architect Brian Goetz's, [who said](https://www.oracle.com/technetwork/articles/javase/devinsight-1-139780.html#1): 

> Often, the way to write fast code in Java applications is to write dumb code — code that is straightforward, clean, and follows the most obvious object-oriented principles.

This is an extension of the [KISS principle](https://en.wikipedia.org/wiki/KISS_principle) and basically means: avoid being clever. Write simple code the way it was meant to be written. Know and write [effective Java](https://www.pearson.com/us/higher-education/program/Bloch-Effective-Java-3rd-Edition/PGM1763855.html).

But there's another advantage to "dumb code:" the compiler knows how to optimize it. So you pick up performance improvements as well.


## Start with the most defensive option

You may have heard some advice that you should limit the visibility of methods or variables and yadda-yadda-yadda something about encapsulation. It all sounds kind of boring, scientific, and yawn-inducing.

![Duke, the Java mascot, experimenting in a chemistry lab](https://thepracticaldev.s3.amazonaws.com/i/zpxthpf66evk0bz24r1e.jpg)

Meanwhile, most Java tutorials will provide examples of classes where the only accessibility modifier being used is `public`. IDE class generation also seems to default to public classes and methods. If you fully generate a class in an IDE, you're bound to end up with something like this:
 
```java
public class Contact {
    private String name;
    private String emailAddress;

    public Contact(String name, String emailAddress) {
        this.name = name;
        this.emailAddress = emailAddress;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }
}
```

On the contrary, I advise devs to start with the most defensive option possible and relax to a less defensive option only when necessary. So for the above example, make each member variable `final` and [avoid implementing getters or setters](https://dev.to/scottshipp/avoid-getters-and-setters-whenever-possible-c8m) unless you can prove you need them.

Furthermore, default to package-private for any constructors or methods. It may be helpful to review [Java access modifiers](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html).

Thus, the prior code becomes the following before it becomes anything else:

```java
class Contact {
    private final String name;
    private final String emailAddress;

    Contact(String name, String emailAddress) {
        this.name = name;
        this.emailAddress = emailAddress;
    }
}
```

A dev writing code like that is thinking about scope and immutability defensively, which is a good thing. Furthermore, that leads to my next point.

![Duke, the Java mascot, giving a thumbs up](https://thepracticaldev.s3.amazonaws.com/i/qedd8xqzhivh7i0565cx.png)


## Prefer to expose behavior over state

You may have noticed that you can't do anything with an instance of `Contact` that's written according to my "starting point" guideline. Exactly! So you may be wondering where do you go from there? And my answer is: [prefer to expose behavior over state](https://dev.to/scottshipp/encapsulate-state-and-expose-behavior-when-writing-object-oriented-code-ea5).

This forces the question, _what do you want to do with `Contact`?_ There's a big difference between a [data transfer object](https://en.wikipedia.org/wiki/Data_transfer_object) whose purpose actually is to carry state somewhere and a normal object whose purpose should be to provide behavior. 

Perhaps the latter is hard to imagine, so let me provide the example of a simple mail app where what we need from our contact list is the ability to email a contact. In a simple mail app, I would recommend making `Contact` the source of that behavior.

```java
public class Contact implements Emailable {
    // ...

    @Override
    public EmailResult sendEmailTo(Contact destination, String body) {
        // ...
    }
}
```

As the application evolves, maybe this approach goes extinct. But its a good idea at this time. Notice that the name and email address which form the state of the `Contact` object are also used within that object. This organizes state and behavior together in a tidy way and negates the need to share any state publicly.

And if the purpose of `Contact`is to transfer data, make it an [immutable object](https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html) which is both thread-safe and protected from accidental programming errors that set its values incorrectly. 

![Duke, the Java mascot, holding a globe](https://thepracticaldev.s3.amazonaws.com/i/x7r7u0d4ovtcjkelr2h7.png)


## Write comprehensive tests

Testing is often the first step put on the chopping block under deadline pressure. This unfortunate result of human psychology is potentially deadly. Java in large, complex applications should be considered buggy until proven otherwise. And only tests can prove otherwise.

> Java in large, complex applications should be considered buggy until proven otherwise.

Get to know a test framework like [JUnit](https://junit.org/) and related tools like [Mockito](https://site.mockito.org/).

Two great resources to learn great testing practices include [xUnit Test Patterns](http://xunitpatterns.com/) by Gerard Meszaros and [Pragmatic Unit Testing in Java 8](https://pragprog.com/book/utj2/pragmatic-unit-testing-in-java-8-with-junit) by Jeff Langr.


## Fix linter and IDE warnings

In addition to what the compiler tells you, let the IDE and static analysis tools like [CheckStyle](https://checkstyle.org/) inform you of ways your code can be more modern, secure, and correct. IntelliJ IDEA has a great [code inspections](https://www.jetbrains.com/help/idea/code-inspection.html) feature that is like having a Java expert at your side as you build your application. Don't waste that advice!

 ![IntelliJ Code Inspections, courtesy of IntellIJ Hel](https://thepracticaldev.s3.amazonaws.com/i/nahkdxtkpo0ysu1foeoa.gif)
_IntelliJ Code Inspections, courtesy of IntellIJ Help_


## Production Java!

Following these tips will result in production-ready Java! That is: Java that can withstand the wild. Java is a great language with a helpful compiler and a strong ecosystem of tools and libraries to help increase and insure quality. By following best practices and making use of these tools, I'm sure that any application can be improved, and you as a Java dev can get busy with what's important--building your application--rather than spending all your time fixing bugs that could have been caught earlier. Good luck!