A class which object state or properties cannot be changed once it is created are known as immutable class. Immutable objects are thread-safe so you will not have any synchronisation issues. Immutable objects are good Map keys and Set elements, since these typically do not change once created. Immutability makes it easier to parallelise your program as there are no conflicts among objects.
All primitive wrapper classes (Integer, Byte, Long, Float, Double, Character, Boolean and Short) are immutable in Java, so operations like addition and subtraction create a new object and not modify the old.
Key points
1. | Define class with final keyword |
2. | Declare all data member as private and final |
3. | Initialize all data member inside constructor only |
4. | Don't provide setter method |
5. | If class has collection object as data member, either return unmodifiable collection or return copy of collection object. |
6. | If class has other immutable object, create clone object and return |
7. | Override clone method |
1 public final class <class_name> {
2 private final <data_type> <variable_name>;
3
4 public <constructor>(<parameter>) {
5
6 }
7
8 public <type> clone() {
9 }
10 }
Immutable class with primitive or immutable fields
Immutable class with primitive or immutable fields
1 package com.java;
2
3 public final class Employee implements Cloneable {
4
5 private final int id;
6 private final String name;
7 private final String email;
8
9 Employee(int id, String name, String email) {
10 this.id = id;
11 this.name = name;
12 this.email = email;
13 }
14
15 public int getId() {
16 return id;
17 }
18
19 public String getName() {
20 return name;
21 }
22
23 public String getEmail() {
24 return email;
25 }
26
27 @Override
28 public Employee clone() {
29 return new Employee(this.id, this.name, this.email);
30 }
31 }
In the above example, a Employee class is define with final keyword that does not allows to override the class. The members of class are define as blank final that initialize only inside constructor. A clone() method is override by creating a new object of Employee class. A members of class are accessible only via getter method.
Class with other class reference
Class with other class reference
1 package com.java;
2
3 public final class Employee implements Cloneable {
4 private final int id;
5 private final String name;
6
7 private final String email;
8 private final Address address;
9
10 Employee(int id, String name, String email, Address address) {
11 this.id = id;
12 this.name = name;
13 this.email = email;
14 this.address = address;
15 }
16
17 public int getId() {
18 return id;
19 }
20
21 public String getName() {
22 return name;
23 }
24
25 public String getEmail() {
26 return email;
27 }
28
29 public Address getAddress() {
30 return new Address(this.address.getStreet(), this.address.getCity(),
31 this.address.getCountry(), this.address.getPincode());
32 }
33
34 @Override
35 public Employee clone() {
36 Address address = new Address(this.address.getStreet(), this.address.getCity(),
37 this.address.getCountry(), this.address.getPincode());
38
39 return new Employee(this.id, this.name, this.email, address);
40 }
41 }
In the above example, if a class includes member as reference of other class Address. If Address class not support clone() method, a new object of Address class should be return from the getAddress() method and in the clone() method it should create new instance and set new object to the copy of Employee clone object.
Class with collection object as member
Class with collection object as member
1 package com.java;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 public final class Employee implements Cloneable {
7 private final int id;
8 private final String name;
9
10 private final String email;
11 private final List<Address> addresses;
12
13 Employee(int id, String name, String email, List<Address> addresses) {
14 this.id = id;
15 this.name = name;
16 this.email = email;
17 this.addresses = addresses;
18 }
19
20 public int getId() {
21 return id;
22 }
23
24 public String getName() {
25 return name;
26 }
27
28 public String getEmail() {
29 return email;
30 }
31
32 public List<Address> getAddress() {
33
34 return new ArrayList<>(this.addresses);
35 }
36
37 @Override
38 public Employee clone() {
39
40 List<Address> lists = new ArrayList<>(this.addresses);
41 return new Employee(this.id, this.name, this.email, lists);
42 }
43 }
In the above example, a class Employee includes a list of addresses. If a class includes a collection object, it should returns as new collection object that may created either with copy of objects and assign to new collection object or just pass collection object.
Related options for your search