java 可变对象 不可变对象,Java不可变对象

I am learning the concept of immutability.

I understand that immutable objects cannot change their values once the object is created.

But I didn't understand the following uses of immutable objects.

They are

are automatically thread-safe and have no synchronization issues. How ? Proof ?

do not need a copy constructor. How ? Any example ?

do not need an implementation of clone How ? Any example ?

do not need to be copied defensively when used as a field How ? Any example ?

always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state. How ? Any example ?

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

Thanks.

解决方案

..are automatically thread-safe and have no synchronization issues

Concurrency problems happen when two different threads modify the state of the same object. Immutable objects can't be modified, so no problems.

Example: A String. Two threads can be passed the same String without worry since neither can mutate it in any way.

do not need a copy constructor

... because copy is the only way to mutate it. One common design pattern for immutable objects for every "modification" operation to make a copy and then perform the operation on the new object.

Copy constructors are usually used on objects that you want to change without affecting the original. This is always the case (by definition) with immutable objects.

In the case of String, all the methods and the + operator return new Strings.

do not need an implementation of clone

see above.

do not need to be copied defensively when used as a field

Once upon a time I did something silly. I had a set of enums in a List:

private static final List validStatuses;

static {

validStatuses = new ArrayList();

validStates.add(Status.OPEN);

validStates.add(Status.REOPENED);

validStates.add(Status.CLOSED);

}

This list was returned from a method:

public static List getAllStatuses() {

return validStates;

}

I retrieved that list but only wanted to show the open states in the interface:

List statuses = Status.getAllStatuses();

statuses.remove(Status.CLOSED);

Great, it worked! Wait, now all status lists are showing only those two -- even after page refresh! What happened? I modified a static object. Oops.

I could have used defensive copying on the return object of getAllStatuses. Or, I could use something like Guava's ImmutableList in the first place:

private static final List validStatuses =

ImmutableList.of(Status.OPEN, Status.REOPENED, Status.CLOSED);

Then when I did something dumb:

List statuses = Status.getAllStatuses();

statuses.remove(Status.CLOSED); // Exception!

always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state.

Because the class can never be modified, all states emitted by modification are whole, qualified objects (because they cannot change, they must always be in a qualified state to be useful). An exception would not emit a new object and therefore you can never have an undesirable or indeterminate state.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值