Search code examples
javaimmutabilityfinal

Immutability property in java


I know that when it comes to passing objects in java, the reference of object is passed as value. So what ever changes you make to that object is reflected in the original object as well. To avoid this we make use of immutability property in java.

So my question is, I have created an immutable class Employee, When I pass an object of this Employee class to some method in other class, I don't want that method to make any changes to this object. Even if it does, I don't want the changes to be affected to the original object created in the calling class.

Here is my sample code.

public final class Employee {
    int employeeId;

    public int getId() {
        return employeeId;
    }

    public void setId(int id) {
        this.employeeId = id;
    }

}

public class Worker {
    public static void process(Employee f, Employee g){
        int c = f.getId();
        f.setId(g.getId());
        g.setId(c);
    }
}

public class ImmutabilityTest{

    public static void main(String[] args) {
        Employee teamMember = new Employee();
        Employee teamLead = new Employee();
        teamMember.setId(5);
        teamLead.setId(10);
        System.out.println("Before process "+teamMember.getId() + " " + teamLead.getId());
        Worker.process(teamMember, teamLead);
        System.out.println("After process "+teamMember.getId() + " " + teamLead.getId());
    }
}

The output will be

Before process 5 10
After process 10 5

Is there any way to avoid the change in the values of the member variables of the Employee class ? (apart from making them final)If not then how are we actually exploiting the Immutability property in java in user defined class ?

Any suggestions/opinions/pointers are appreciated ! Thanks..


Solution

  • Immutability is not a property in Java that can be applied to an Object with a single keyword, its a strategy that needs to be implemented on a case by case basis. Generally speaking, you utilize the final keyword and cloning in order to accomplish this. Note that the deeper your object nesting, the greater the level of difficulty in achieving true object immutability.

    Here is a (more) immutable version of your Employee class:

    public class Employee {
        final int employeeId;
    
        public Employee(final int id) {
            super();
            this.employeeId = id;
        }
    
        public int getId() {
            return employeeId;
        }
    }
    

    Note that reflection in Java makes it practically impossible to achieve true immutability, even with the use of the final instance variables and cloning.