As this is a hot topic these days, I fail to understand certain concept. Please excuse me if I sound stupid but when I tried creating immutable object most of the posts I found following points
- Make class final - makes sense
- Dont allow mutators (setters) for the attributes - makes sense
- Make attributes private - makes sense
Now I fail to understand why we need below points
- Make constructor private and provide createInstance method with the same attributes as constructor or factory method ? How does it help ?
- Make attributes final - post of the post fail to explain this point and some where I read to avoid the modification accidentally. How can you modify accidentally, when there are no mutators and class is final ? How making an attribute final is helping ?
- Instead of factory pattern, can I use builder pattern ?
I am adding my class and test case here :
    public final class ImmutableUser {
    private final UUID id;
    private final String firstName;
    private final String lastName;
    public ImmutableUser(UUID id, String firstName, String lastName) {
        super();
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    /**
     * @return the id
     */
    public UUID getId() {
        return id;
    }
    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }
    /**
     * @return the lastName
     */
    public String getLastName() {
        return lastName;
    }
}
Test case
public class ImmutableUserTest {
        @Test(expected = IllegalAccessException.class)
        public void reflectionFailure() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
            ImmutableUser user = new ImmutableUser(UUID.randomUUID(), "john", "liu");
            Field i =user.getClass().getDeclaredField("firstName");
            i.setAccessible(true);
            i.set(user, "cassandra");
            System.out.println("user " + user.getFirstName()); // prints cassandra
        }
    }
This test case fails and prints cassandra.
Let me know if I am doing something wrong.
 
     
     
     
    