The following code violates the encapsulation principle, because the getHireDay() method returns a Date object. To change it somewhere in another class that called the getHireDay() method means to change the state of the Employee object.

 class Employee { private Date hireDay; public Date getHireDay(); { return hireDay; } } 

In the following code, the problem seems to be resolved. Changing the state of an Employee object somewhere in another class that called the getHireDay() method will fail.

 class Employee { private Date hireDay; public Date getHireDay(); { return hireDay.clone(); } } 

Question. Is changing the state of an object a problem, because there can be as many objects of this class? In which cases it is necessary to take care of the state of the object, more precisely, about the immutability of its state?

  • When you call the getHireDay () method, the state of the object does not change at all. For example, the setter is changing - Dmitri
  • 3
    In my opinion, it depends on the specific situation. If it is important not to make it possible to change the contents of the field, and also that copying an object is not a problem in terms of performance, then you can return a copy. In some situations, in general, instead of the object itself, you can return a specific value from it, without exposing the object itself to a “threat”. - Regent
  • But on the returned Date you can change the state (for example, using the setTime method), which does change the state of Employee , because it will change the date of employment. - Regent
  • 2
    The problem described is called unsafe publication. In some situations, it is irrelevant. In others, it is dangerous. - Nofate ♦

1 answer 1

Objects can always be divided into two types:

  1. mutable (changeable)
  2. unbutable (unchangeable)

What are mutable objects: these are objects that have a state and have methods for changing this state. Those. Plain Old Java Objects with getters and setters that are familiar to us.

Unmucable - these are objects that, after their creation (invocation of the constructor), cannot change.

Each of these types has its advantages and disadvantages.

Advantages of unbutability:

  1. Immutable objects are good keys in Map and Set, since they usually do not change after creation.
  2. Non-confusion simplifies writing, using and understanding the code (the class invariant is set once and then unchanged)
  3. Immutability simplifies the parallelization of your program, since there are no conflicts between objects.
  4. The internal state of your program will be consistent, even if you have exceptions.
  5. References to immutable objects can be cached, since they will not change.
  6. Immutable objects are thread-safe, so you will not have problems with synchronization.

But you have to pay for these advantages, so you have to spend time creating new objects, every time you want to change the state, you will also have to think about which object can be called un-stable, because your object is unfortunately mutable. Those. you need to keep in mind the rules for creating unmovable objects, namely

  1. Make all fields private
  2. Do not provide getters / setters and other mutators.
  3. Ensure that methods cannot be overridden by creating a final class (Strong Immutability) or making your methods final (Weak Immutability)
  4. If the field is not primitive or unsuitable (like Date), then make a complete cloning of this object.

In general, the answer to your question: mutability itself is not a problem! It is actively used in the development, when the subject area is represented by an anemic data model (only getters / setters and there are no methods of behavior in objects), and everyone lives with it perfectly. But if you want to call an object immutable, use it as a key in a map, use it in a multithreaded environment, then take care of the points mentioned above.

  • Amendment: immutable objects are called immutable - Pavel Mayorov