Immutable Class with List
package com.text.immutable;
import java.util.Collections;
import java.util.List;
// An immutable class Student
public final class Student
{
final String name;
final int regNo;
final List<String> courses; // want to make Immutable
public Student(String name, int regNo, List<String> courses)
{
this.name = name;
this.regNo = regNo;
this.courses = Collections.unmodifiableList(courses);
}
public String getName()
{
return name;
}
public int getRegNo()
{
return regNo;
}
public List<String> getCourses() {
return courses;
}
}
Testing Immutable Class to Break Immutability
package com.text.immutable;
import java.util.ArrayList;
import java.util.List;
class ImmutablityTest
{
public static void main(String args[])
{
List<String> courses = new ArrayList<String>();
courses.add("java");
courses.add("spring");
courses.add("hibernate");
courses.add("rest");
Student s = new Student("ABC", 101, courses);
System.out.println("Before Update List");
System.out.println(s.getName());
System.out.println(s.getRegNo());
System.out.println(s.getCourses());
courses.add("Hibernate"); // Able to Change which affect final OutCome
//s.getCourses().add("SpringBoot"); // giving Exception in thread "main" java.lang.UnsupportedOperationException
System.out.println("After Update List");
System.out.println(s.getName());
System.out.println(s.getRegNo());
System.out.println(s.getCourses());
}
}
Output is
Before Update List
ABC
101
[java, spring, hibernate, rest]
After Update List
ABC
101
[java, spring, hibernate, rest, Hibernate]
why and how this new Course element added into the List as its from Client Side can be added up any time so how we can fix this issue as this immutable class should not allow to modifying after once created
this.courses = Collections.unmodifiableList(courses);
That creates, as the name says, an unmodifiable list. But that is just a view on the original list. Thus changes to that original list become visible in your "unmodifiable" view.
When in doubt: clone your list, like:
this.courses = new ArrayList<>(courses);
And then ensure that your getter does:
return Collections.unmodifiableList(courses);