Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in Java by (7k points)

How to create immutable objects in Java?

Which objects in Java are called as immutable?

If I have a class with all static members is it immutable?

1 Answer

0 votes
by (13.1k points)

Here are some requirements of an immutable object.

  1. Make the class final

  2. Make all members final, set them explicitly, in a static block, or in the constructor

  3. Make all members private

  4. No methods that modify the state

  5. Be extremely careful to limit access to mutable members. You should make defensive copies in these cases.

The reasoning behind making the class final is very subtle and often overlooked. If it is not final people can freely extend your class, override public or protected behavior, add mutable properties, then supply their subclass as a substitute. By declaring class final you can ensure this will not happen.

To understand the problem see the example below:

public class MyApp{

    /**

     * @param args

     */

    public static void main(String[] args){

        System.out.println("Hello World!");

        OhNoMutable mutable = new OhNoMutable(1, 2);

        ImSoImmutable immutable = mutable;

        /*

         * Ahhhh Prints out 3 just like I always wanted

         * and I can rely on this super immutable class 

         * never changing. So its thread safe and perfect

         */

        System.out.println(immutable.add());

        /* Some sneak programmer changes a mutable field on the subclass */

        mutable.field3=4;

        /*

         * Ahhh let me just print my immutable 

         * reference again because I can trust it 

         * so much.

         * 

         */

        System.out.println(immutable.add());

        /* Why is this buggy piece of crap printing 7 and not 3

           It couldn't have changed its IMMUTABLE!!!! 

         */

    }

}

/* This class adheres to all the principles of 

*  good immutable classes. All the members are private final

*  the add() method doesn't modify any state. This class is 

*  just a thing of beauty. Its only missing one thing

*  I didn't declare the class final. Let the chaos ensue

*/ 

public class ImSoImmutable{

    private final int field1;

    private final int field2;

    public ImSoImmutable(int field1, int field2){

        this.field1 = field1;

        this.field2 = field2;

    }

    public int add(){

        return field1+field2;

    }

}

/*

This class is the problem. The problem is the 

overridden method add(). Because it uses a mutable 

member it means that I can't guarantee that all instances

of ImSoImmutable are actually immutable.

*/ 

public class OhNoMutable extends ImSoImmutable{   

    public int field3 = 0;

    public OhNoMutable(int field1, int field2){

        super(field1, field2);          

    }

    public int add(){

       return super.add()+field3;  

    }

}

It is very common for you to encounter the above problem in Dependency Injection environments. You are not explicitly instantiating things and the super class reference you are given may actually be a subclass.

The takeaway is that to make hard guarantees about immutability you have to mark the class as final.

Want to learn Java? Check out the Java certification from Intellipaat.

Related questions

0 votes
1 answer
asked Feb 23, 2021 in Java by Jake (7k points)
0 votes
2 answers
asked Feb 18, 2021 in Java by Harsh (1.5k points)
0 votes
1 answer
asked Oct 29, 2019 in Java by Anvi (10.2k points)
0 votes
1 answer
0 votes
1 answer
asked Oct 23, 2019 in Java by Anvi (10.2k points)

31k questions

32.8k answers

501 comments

693 users

Browse Categories

...