x Java Java 8 JUnit JSON
  • XML
  • JDBC Spring Boot Microservices React Contact Us

    How to create immutable class in Java ?

    An immmutable class is a class whose state can not be changed once its instance has been created. There are many immmutable classes in Java for e.g. String class, Integer class.

    Benefits of using immmutable class:

    • An immutable class is useful when you want to use object for caching purpose for e.g. in HashSet or key in a HashMap because you don’t need to worry about the value changes.
    • An immutable class is inherently thread-safe.
    • Immutable objects are very useful in concurrent applications as their state cannot be changed state, so they cannot be corrupted or in consistent state if changed by multiple threads.

    To create immutable class in Java, follow these rules:

    • Class should be declared as final, so it can't be extended.
    • Class attributes should be declared as final.
    • Class should not have any setter methods.
    • Make all class attributes private.
    • Make defensive copies of fields that are mutable and return those.

    1) Example below shows a mutable class

    In this example we are using setter method for setting the day attribute, but we should not provide settter method for day attribute as we are not supposed to change the day state.

    // mutable class	
    public final class MutableDay { 
        private String day;
          
        public MutableDay(String day) {
            this.day = day; 
        }
                
        public String getDay() {
            return this.day; 
        }
                        
        public void setDay(String day) {
            this.day = day;
        }
        
        public static void main(String[] args) {
            MutableDay day = new MutableDay("Monday");
            System.out.println(day.getDay());
            day.setDay("Tuesday");
            System.out.println(day.getDay());
        }
    }
            

    Output :

    Monday
    Tuesday	

    2) Example below shows how can we make above class immutable by removing setter method for day attribute

    // immutable class	
    public final class ImmutableDay { 
        private final String day;
          
        public ImmutableDay(String day) {
            this.day = day; 
        }
                
        public String getDay() {
            return this.day; 
        }
                        
        public static void main(String[] args) {
            ImmutableDay day = new ImmutableDay("Monday");
            System.out.println(day.getDay());
        }
    }
            

    Output :

    Monday
    	

    3) Example below shows a mutable class with List type attribute

    In this example in getDays() we should not return original copy of days List, as it can be modifled by someone. Also you should not provide setter method for days List as someone can modify the days List.

    import java.util.List;
    import java.util.ArrayList;
            
    // mutable class	
    public final class MutableDay { 
        private List<String> days; 
          
        public MutableDay(List<String> days) {
            this.days = days;
        }
                
        public List<String> getDays() {
            return this.days; 
        }
                        
        public void setDays(List<String> days) {
            this.days = days;
        }
        
        public static void main(String[] args) {
            List<String> days = new ArrayList<String>();
            days.add("Monday");
            days.add("Tuesday");
            days.add("Wednesday");
            MutableDay day = new MutableDay(days);
            days = day.getDays();
            System.out.println(days);
            days.remove("Wednesday");
            System.out.println(day.getDays());
        }
    }
            

    Output :

    [Monday, Tuesday, Wednesday]
    [Monday, Tuesday]	

    4) Example below shows how to make above class immutable by creating a copy of days List when returning it and removing the setter method for days List

    // immutable class	
    import java.util.List;
    import java.util.ArrayList;
    	
    public final class ImmutableDay { // immutable class should be final 
        private final List<String> days;  // immutable class attributes should be final
          
        public ImmutableDay(List<String> days) {
            this.days = days;
        }
                
        // return copy of days instead of actual data
        public List<String> getDays() {
             return new ArrayList<String>(this.days); 
        }
                
        public static void main(String[] args) {
            List<String> days = new ArrayList<String>();
            days.add("Monday");
            days.add("Tuesday");
            days.add("Wednesday");
            ImmutableDay day = new ImmutableDay(days);
            days = day.getDays();
            System.out.println(days);
            days.remove("Wednesday");
            System.out.println(day.getDays());
        }
    }        

    Output :

    [Monday, Tuesday, Wednesday]
    [Monday, Tuesday, Wednesday]	

    5) Example below shows a mutable class with Date type attribute.

    In this example in getPublishedDate() method we should not return exact copy of publishedDate, as it can be modifled by someone.

    import java.util.Date;
            
    // mutable class	
    public final class MutableBook { 
        private String bookName;
        private Date publishedDate;
          
        public MutableBook(String bookName, Date publishedDate) {
            this.bookName = bookName;
            this.publishedDate = publishedDate;
        }
                
        public String getBookName() {
            return this.bookName; 
        }
                        
        public Date getPublishedDate() {
            return this.publishedDate; 
        }
        
        public static void main(String[] args) {
            MutableBook book = new MutableBook("Lord of the Rings" , new Date(1997, 10, 01));
            System.out.println(book.getBookName());
            Date publishedDate = book.getPublishedDate();
            System.out.println("Actual published date " + publishedDate);
            publishedDate.setYear(2018);
            System.out.println("Modified published date " + book.getPublishedDate());
        }
    }
            

    Output :

    Lord of the Rings
    Actual published date Mon Nov 01 00:00:00 IST 3897
    Modified published date Fri Nov 01 00:00:00 IST 3918	

    6) Example below shows how to create immutable class in Java with Date type attribute.

    In this example we return a copy of publishedDate instead of returning the actual publishedDate instance. The caller of this method can't modify the original Date object.

    import java.util.Date;
            
    // immutable class	
    public final class ImmutableBook { 
        private String bookName;
        private Date publishedDate;
          
        public ImmutableBook(String bookName, Date publishedDate) {
            this.bookName = bookName;
            this.publishedDate = publishedDate;
        }
                
        public String getBookName() {
            return this.bookName; 
        }
                        
        public Date getPublishedDate() {
            return new Date(publishedDate.getTime());
        }
        
        public static void main(String[] args) {
            ImmutableBook book = new ImmutableBook("Lord of the Rings" , new Date(1997, 10, 01));
            System.out.println(book.getBookName());
            Date publishedDate = book.getPublishedDate();
            System.out.println("Actual published date " + publishedDate);
            publishedDate.setYear(2018);
            System.out.println("Modified published date " + book.getPublishedDate());
        }
    }        

    Output :

    Lord of the Rings
    Actual published date Mon Nov 01 00:00:00 IST 3897
    Modified published date Mon Nov 01 00:00:00 IST 3897	


    References :

    Oracle Docs Immutable objects

    Oracle Docs String class

    Comments

    Leave a Reply

    Your email address will not be published. Required fields are marked *











    Share This