Saturday, June 16, 2018

How do you create Immutable class in java?

Problem statement: How do you make any java class immutable?
  1. Class must be declared as final (So that child classes can’t be created)
  2. Data members in the class must be declared as final (So that we can’t change the value of it after object creation)
  3. A parameterized constructor
  4. Getter method for all the variables in it
  5. No setters(To not have option to change the value of the instance variable)
  • When exposing methods which modify the state of the class, you must always return a new instance of the class.
  • If the class holds a mutable object:
    • Inside the constructor, make sure to use a clone copy of the passed argument and never set your mutable field to the real instance passed through constructor, this is to prevent the clients who pass the object from modifying it afterwards.
    • Make sure to always return a clone copy of the field and never return the real object instance
1) Don’t provide “setter” methods — methods that modify fields or objects referred to by fields.
This principle says that for all mutable properties in your class, do not provide setter methods. Setter methods are meant to change the state of object and this is what we want to prevent here.
2) Make all fields final and private
This is another way to increase immutability. Fields declared private will not be accessible outside the class and making them final will ensure the even accidentally you can not change them.
3) Don’t allow subclasses to override methods
The simplest way to do this is to declare the class as final. Final classes in java can not be overridden.
4) Special attention when having mutable instance variables
Always remember that your instance variables will be either mutable or immutable. Identify them and return new objects with copied content for all mutable objects. Immutable variables can be returned safely without extra effort.
A more sophisticated approach is to make the constructor private and construct instances in factory methods.
  1. import java.util.Date;
  2.  
  3. /**
  4. * Always remember that your instance variables will be either mutable or immutable.
  5. * Identify them and return new objects with copied content for all mutable objects.
  6. * Immutable variables can be returned safely without extra effort.
  7. * */
  8. public final class ImmutableClass
  9. {
  10.  
  11.     /**
  12.     * Integer class is immutable as it does not provide any setter to change its content
  13.     * */
  14.     private final Integer immutableField1;
  15.     /**
  16.     * String class is immutable as it also does not provide setter to change its content
  17.     * */
  18.     private final String immutableField2;
  19.     /**
  20.     * Date class is mutable as it provide setters to change various date/time parts
  21.     * */
  22.     private final Date mutableField;
  23.  
  24.     //Default private constructor will ensure no unplanned construction of class
  25.     private ImmutableClass(Integer fld1, String fld2, Date date)
  26.     {
  27.         this.immutableField1 = fld1;
  28.         this.immutableField2 = fld2;
  29.         this.mutableField = new Date(date.getTime());
  30.     }
  31.  
  32.     //Factory method to store object creation logic in single place
  33.     public static ImmutableClass createNewInstance(Integer fld1, String fld2, Date date)
  34.     {
  35.         return new ImmutableClass(fld1, fld2, date);
  36.     }
  37.  
  38.     //Provide no setter methods
  39.  
  40.     /**
  41.     * Integer class is immutable so we can return the instance variable as it is
  42.     * */
  43.     public Integer getImmutableField1() {
  44.         return immutableField1;
  45.     }
  46.  
  47.     /**
  48.     * String class is also immutable so we can return the instance variable as it is
  49.     * */
  50.     public String getImmutableField2() {
  51.         return immutableField2;
  52.     }
  53.  
  54.     /**
  55.     * Date class is mutable so we need a little care here.
  56.     * We should not return the reference of original instance variable.
  57.     * Instead a new Date object, with content copied to it, should be returned.
  58.     * */
  59.     public Date getMutableField() {
  60.         return new Date(mutableField.getTime());
  61.     }
  62.  
  63.     @Override
  64.     public String toString() {
  65.         return immutableField1 +" - "+ immutableField2 +" - "+ mutableField;
  66.     }
  67. }

No comments:

Post a Comment

How to run standalone mock server on local laptop

 Please download the standalone wiremock server from Direct download section at the bottom of the page.  Download and installation Feel fre...