Immutable class plays very important role in Java programming and also you can expect questions on Immutability concept almost in every Java interview.
1.What is Immutable class?
Answer: Immutable class is a special kind of class which is used to ensure that once you created an object and defined it's state, you can not modify the object's state. If you will try to modify, you should get a new object with your changes but original object and it's state will remain same.
So we can say that as per the concept of Immutability once you created an object and define it's state(values), you can not modify it further.
2.How to design an Immutable class ?
Answer: To design an Immutable class we need to follow below steps:
Example: In below code we have an Immutable class Employee. We have marked class as final and variables are marked as private and final.
At line number 3 we have initialized our emp object and then at line number 7 and 8 we did some modification. If you run below code you will get same value printed for emp object in console both the time.
Reason behind for such behavior is that String, Integer etc. are inbuilt immutable class of Java.
So if member variables are already immutable then you don't need to worry about their modification.
Note : If you have reference variable of Mutable type(for example Date class) then you need to put extra care in your code.
2. There should be no setter method for member variables(only getter methods for access): This is because there is no need of setting values again once object is initialized via constructor.
3.Mark your class as Final: By marking class as Final we are restricting other classes from extending it. If other classes are allowed to extend immutable class, they can override functionalities which can break the immutability feature.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| public class TestMutability {
public static void main(String[] args) {
Employee emp = new Employee(1234, "John", 27);
System.out.println("Employee details: "+emp.toString());
String empName = emp.getEmpName();
Integer empAge = emp.getEmpAge();
empName = "Tom";
empAge = 25;
System.out.println("After modification");
System.out.println("Employee details: "+emp.toString());
}
}
final class Employee{
final private Integer empId;
final private String empName;
final private Integer empAge;
public Employee(Integer empId, String empName, Integer empAge) {
this.empId = empId;
this.empName = empName;
this.empAge = empAge;
}
public Integer getEmpId() {
return empId;
}
public String getEmpName() {
return empName;
}
public Integer getEmpAge() {
return empAge;
}
@Override
public String toString(){
return"Employee Id: " + empId + ", Employee Name: "+ empName + ", Employee Age: " + empAge;
}
}
|
So we can say that if all your reference member variables are immutable and you have incorporated above three rules then your class will be an Immutable class. If you have mutable reference member variables then you need to take extra care of those reference member variable.
Follow-up Question: How will you handle mutable reference variable scenario?
Answer: In below code we have added joiningDate varaible in Employee class which is of Date type. Date is inbuilt mutable class in Java. At line number 41 inside getJoiningDate method where instead of returning actual object we are returning clone of it. So any modification in joiningDate variable at line number 9 won't impact original joiningDate of Employee class as we working on clone object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| import java.util.Date;
public class TestMutability {
public static void main(String[] args) {
Employee emp = new Employee(1234, "John", 27);
System.out.println("Employee details: "+emp.toString());
String empName = emp.getEmpName();
Integer empAge = emp.getEmpAge();
Date joiningDate = emp.getJoiningDate();
joiningDate.setDate(10);
empName = "Tom";
empAge = 25;
System.out.println("After modification");
System.out.println("Employee details: "+emp.toString());
}
}
final class Employee{
final Integer empId;
final String empName;
final Integer empAge;
final Date joiningDate;
public Employee(Integer empId, String empName, Integer empAge) {
this.empId = empId;
this.empName = empName;
this.empAge = empAge;
joiningDate = new Date();
}
public Integer getEmpId() {
return empId;
}
public String getEmpName() {
return empName;
}
public Integer getEmpAge() {
return empAge;
}
public Date getJoiningDate() {
return (Date)joiningDate.clone();
}
@Override
public String toString(){
return"Employee Id: " + empId + ", Employee Name: "+ empName + ", Employee Age: " + empAge+", Joining Date:"+joiningDate;
}
}
|
So we can say that to handle mutable reference variable we shouldn't return original object instead we should return clone (or by creating new object) of original object.
3. How many object will get created in below codes and why?
1.1
2
3
4
5
6
| public class StringExample {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = new String("Hello");
}
}
|
2.
1
2
3
4
5
6
| public class StringExample {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "Hello";
}
}
|
3.
1
2
3
4
5
6
| public class StringExample {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = s1+"World";
}
}
|
Answer: In above code 2 objects will get created : one object will get created at line 3 in String pool and one more object will get created at line 4 in String pool. Since String is immutable and we are trying to modify value of s1 which will result in new object as per immutability rules.
So final value of variables will be like as follow: Value of s1 will be "Hello" and Value of s2 will be "HelloWorld".
Note: There are two ways we can create String object which are as follows:
1. String s1 = "Hello" - In this case object always create only in String pool if and only if there is no string constant with same value exist in pool otherwise same will use.
2. String s1 = new String("Hello") - In this case one object always create in Heap and second in String pool if and only if there is no string constant with same value exist in pool otherwise same will use.
No comments:
Post a Comment