Skip to content

What is Immutability in Java Functional Programming?

In this lesson, you will learn how immutability is achieved through functional programming.

Gopi Gorantala
Gopi Gorantala
3 min read

Table of Contents

One of the major concepts in functional programming is immutability.

The definition that you can see in Wikipedia states that an immutable object is one whose state cannot be modified after it is created. Or in other words, some variable that can’t change its value.


An immutable object is an object whose state cannot be modified after it is created. In multi-threaded applications that is a great thing. It allows a thread to act on data represented by immutable objects without worrying about what other threads are up to.

Java provides several built-in classes that are immutable, such as String, Integer, BigDecimal, LocalDate, and LocalTime. These classes are designed to be thread-safe and can be shared among threads without the risk of concurrent modification.

What does immutability mean?

In object-oriented and functional programming, an immutable (unchangeable object) is an object whose state cannot be modified after creation. This contrasts with a mutable (changeable object), which can be modified after creation.

We were taught how to assign a value to a variable.

For example, int data = 100, and then later on we change the value of data to data=200 and later, we change this value from 200 into something else.

So what’s so special in dealing with value changes?

This is important to us, as the value is changing each time, the state of the object is getting changed, and at some point, we run into an issue where we don’t know the exact state change that happened so far in the code.

In Functional programming, this variable change is not allowed. When we assign a value to a variable, it remains the same throughout the program, and there is no way to change its value. In short, immutability means we must treat most values as constants. We can use the java keyword final one way to declare it, or we write our application so that it won’t do modifications.

In imperative programming, we treat the variables as buckets. Each time we can change the value, the bucket holds the new value in each state change.

In Functional programming, we don’t assign values as in imperative programming. When we say int data = 100, we mean data is another name for 100 or data is 3.

Book Object  

Book book = new Book("Show Your Work", 9.99); // cost in euros

We can increase the cost of the book by calling a setter on the book class.

book.setCost(14.99); // setters changes the value to its new state.

Above is how we do it in the imperative type of programming.

In functional programming, we would instead define a new Book that represents the updated data and then uses this new Book in our future calculations.

So the advantage of having functional programming is it freezes from having to deal with the state change.

In a simple program, we can keep track of variables changing at each state. But what if there are a lot of variables, and the values change at different times when the program is running? It's hard to know the program's exact state at any given time. So Imagine a program that increases to have thousands or millions of variables for a massive application. It's tough to find bugs. On the other hand, functional programming starts with an immutable data set as a single source of truth. Then, it uses functional programming to combine the data piece by piece and transform it into useful information.


Creating immutable objects has several advantages.

  1. It makes code easier to reason about and test, as there is no need to worry about unexpected changes to the object's state.
  2. It helps prevent bugs related to race conditions and concurrent access to shared objects.
  3. It can improve performance in some cases, as immutable objects can be cached and reused instead of creating new objects whenever needed.
  4. Original data in a program will always remain intact, making bugs much easier to find.
  5. Programs constructed this way are much easier to track since we can focus on any piece individually. The only thing that determines the output of a given piece is the input. We don’t have to think about the entire system all the time

Gopi Gorantala Twitter

Gopi is a highly experienced Full Stack developer with a deep understanding of Java, Microservices, and React. He worked in India & Europe for startups, the EU government, and tech giants.


Related Posts

Members Public

How To Write Lambda Expressions

This lesson introduces the basic lambda expression structure with tips to write efficient code.

Members Public

What Are Lambda Expressions?

This is an introductory lesson on lambda expressions. You will learn about the lambda operator, expression, syntaxes and more!

Members Public

Power Of Two (Exercise Problem)

This is an exercise problem for your practice. Try to come up with an approach and solve it by yourself. Good Luck!