0%

不可变对象

不可变对象

不可变对象(Immutable Object):对象一旦被创建后,对象所有的状态及属性在其生命周期内不会发生任何变化。发布不可变对象是安全的。

自定义不可变类

通常来说,创建不可变类原则有以下几条:

  • 所有成员变量必须是private,同时用final修饰

  • 将类声明为final,不允许类被继承

  • 不提供能够修改原有对象状态的方法,最常见的方式是不提供setter方法

  • 通过构造器初始化所有成员变量,引用类型的成员变量必须进行深拷贝(deep copy)

  • get方法中不直接返回对象的本身,而是克隆对象,返回对象的拷贝。

下面是一个Immutable Object的例子,该对象可以用在并发环境下而没有线程安全问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
final public class Person {
private final String name;
private final String address;

public Person(String name,String address){
this.name = name;
this.address = address;
}

public String getName() {
return name;
}

public String getAddress() {
return address;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}

Java unmodifiablexxx

使用Java的Collections类的unmodifiablexxx相关方法,可以创建不可变对象。xxx方法包含:Collection、List、Map、Set….

1
2
3
4
5
6
7
8
9
10
public class ImmutableExample {
public static void main(String[] args) {
HashMap<Integer,Integer> map=new HashMap<>();
map.put(1,1);
map.put(2,2);
Map<Integer, Integer> unmodifiableMap = Collections.unmodifiableMap(map);
log.info("{}", unmodifiableMap.get(1));
unmodifiableMap.put(1, 3);
}
}

UnmodifiableMapmap更新方法(比如put、remove等)进行了重写,均返回UnsupportedOperationException异常,这样就做到了map对象的不可变。

Guava Immutablexxx

使用GuavaImmutablexxx类也可以创建不可变对象。xxx同样包含很多类型:Collection、List、Map、Set….

1
private final static ImmutableMap<Integer, Integer> map = ImmutableMap.of(1, 2, 3, 4);

Immutable相关类使用了跟Java的unmodifiable相关类相似的实现方法。