Unrivaled Java Objects

I study the concept of immutability.

I understand that immutable objects cannot change their values ​​after creating the object.

But I did not understand the following uses of immutable objects.

They

  • Automatically thread safe and have no synchronization problems. How ? Proof ?
  • no copy constructor needed. How ? Any example ?
  • no clone How ? Any example ? implementation required How ? Any example ? How ? Any example ?
  • no need to copy protectively when used as a field How ? Any example ? How ? Any example ?
  • always has "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it never throws in an undesired or undefined state. How ? Any example ?

Can someone please explain each of these points in detail with examples supporting it?

Thanks.

+6
source share
4 answers

.. are automatically thread safe and have no synchronization problems

Problems

Concurrency occurs when two different threads change the state of the same object. Immutable objects cannot be modified, so no problem.

Example: A String . Two streams can be transmitted by the same String without problems, since none of them can mutate it.

no copy constructor required

... because a copy is the only way to mutate it. One common design pattern for immutable objects for each “modification” operation, to make a copy and then perform an operation on a new object.

Copy constructors are typically used for objects that you want to modify without affecting the original. This always takes place (by definition) with immutable objects.

In the case of String all methods and the + operator return a new String s.

no clone implementation required

see above.

no need to copy defensively when used as a field

I used to do something stupid. I had a list of listings in a list:

 private static final List<Status> validStatuses; static { validStatuses = new ArrayList<Status>(); validStates.add(Status.OPEN); validStates.add(Status.REOPENED); validStates.add(Status.CLOSED); } 

This list was returned from a method:

 public static List<Status> getAllStatuses() { return validStates; } 

I got this list, but wanted to show open states in the interface:

 List<Status> statuses = Status.getAllStatuses(); statuses.remove(Status.CLOSED); 

Great, it worked! Wait, now all the status lists show only those two - even after refreshing the page! What happened? I changed the static object. Unfortunately.

I could use protective copying on the returned getAllStatuses object. Or, I could use something like a Guava ImmutableList in the first place:

 private static final List<Status> validStatuses = ImmutableList.of(Status.OPEN, Status.REOPENED, Status.CLOSED); 

Then when I did something dumb:

 List<Status> statuses = Status.getAllStatuses(); statuses.remove(Status.CLOSED); // Exception! 

always has an “atomic failure” (a term used by Joshua Bloch): if an immutable object throws an exception, it never throws in an undesirable or undefined state.

Since the class can never be changed, all the states emitted by the modification are whole, qualified objects (because they cannot change, they must always be in a qualified state in order to be useful). An exception should not cause a new object, and therefore you can never have an unwanted or undefined state.

+10
source

They are automatically thread safe and have no synchronization issues.

Yes due to the guarantees provided by the Java memory model for final fields :

leaf fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is considered immutable for all threads, even if the data race is used to pass references to an immutable object between threads.

no need to copy defensively when used as a field How? Any example?

Since they are immutable, they cannot be changed, so they can be shared with external code (you know that they cannot ruin the state of an object).

Corollary: you do not need to copy / clone immutable objects.

always has a "atomic failure"

An immutable object does not change after the correct assembly. Thus, either a design failure or you get an exception or not, and you know that the object is in a consistent state.

+2
source

This is not a concept that can be usefully explained with its examples. The advantage of immutable objects is that you know that their data cannot change, so you do not need to worry about it. You can use your immutable object freely, without fear that the method in which you pass them will change it.

when we execute a multi-threaded program, than this is convenient because errors based on data modified by threads should not be executed

+1
source

Automatically protect streams

  • because they cannot be changed (cannot mutate) - any thread accessing it finds the object in the same state. Thus, there are no situations such as one thread changing the state of the object, then the second thread captures and changes the state of the object, then again it is taken first without a hint that it was changed by someone else.
  • A good example is an ArrayList - if one thread iterates through its “elements” and the second thread removes some of them, the first thread then throws a concurrency exception. With an immutable list, this is prevented.

Copy constructor

  • this does not mean that it cannot have a copy constructor. This is the constructor to which you pass an object of the same type, and you create a new object as a copy of this object. This is just an assumption, but why do you need to copy an object that is always in the same state?
 public class A { private int a; public A(int a) { this.a = a; } public A(A original) { this.a = original.a; } } 

Clone implementation

  • the same problem, a cloning object that is always in the same state usually takes up only memory space. But you can do this if you want to create a mutable object from immutable
  • A good example is collections again, you can generate a mutable collection from immutable

Defensive copying

  • Protective copy
  • means that when you set an object in a field, you create a new object of the same type, which is a copy of the original
  • Example
0
source

Source: https://habr.com/ru/post/949722/


All Articles