不可变对象
不可变对象需要满足的条件
- 对象创建以后其状态就不能修改
- 对象所有域都是final类型
- 对象是正确创建的(在对象创建期间,this引用没有逸出)
创建不可变对象的方式(参考String类型)
- 将类声明成final类型,使其不可以被继承
- 将所有的成员设置成私有的,使其他的类和对象不能直接访问这些成员
- 对变量不提供set方法
- 将所有可变的成员声明为final,这样只能对他们赋值一次
- 通过构造器初始化所有成员,进行深度拷贝
- 在get方法中,不直接返回对象本身,而是克隆对象,返回对象的拷贝
final关键字:类、方法、变量
- 修饰类:不能被继承(final类中的所有方法都会被隐式的声明为final方法)
- 修饰方法:1、锁定方法不被继承类修改;2、提升效率(private方法被隐式修饰为final方法)
- 修饰变量:基本数据类型变量(初始化之后不能修改)、引用类型变量(初始化之后不能再修改其引用)
其他的不可变对象的创建

其他的不可变对象的创建
- Collections.unmodifiableMap 创建完以后不允许被修改
源码
/**
* 初始化的时候将传进来的map赋值给一个final类型的map,然后将所有会修改的方法直接抛出UnsupportedOperationException异常
* Returns an unmodifiable view of the specified map. This method
* allows modules to provide users with "read-only" access to internal
* maps. Query operations on the returned map "read through"
* to the specified map, and attempts to modify the returned
* map, whether direct or via its collection views, result in an
* <tt>UnsupportedOperationException</tt>.<p>
*
* The returned map will be serializable if the specified map
* is serializable.
*
* @param <K> the class of the map keys
* @param <V> the class of the map values
* @param m the map for which an unmodifiable view is to be returned.
* @return an unmodifiable view of the specified map.
*/
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
return new UnmodifiableMap<>(m);
}
/**
* @serial include
*/
private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
private static final long serialVersionUID = -1034234728574286014L;
private final Map<? extends K, ? extends V> m;
UnmodifiableMap(Map<? extends K, ? extends V> m) {
if (m==null)
throw new NullPointerException();
this.m = m;
}
public int size() {return m.size();}
public boolean isEmpty() {return m.isEmpty();}
public boolean containsKey(Object key) {return m.containsKey(key);}
public boolean containsValue(Object val) {return m.containsValue(val);}
public V get(Object key) {return m.get(key);}
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
public V remove(Object key) {
throw new UnsupportedOperationException();
}
测试
@ThreadSafe
public class ImmutableExample1 {
private static Map<Integer,Integer> map = Maps.newHashMap();
static {
map.put(1,2);
map = Collections.unmodifiableMap(map);
}
public static void main(String[] args) {
//Exception in thread "main" java.lang.UnsupportedOperationException
// at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
// at com.gwf.concurrency.example.immutable.ImmutableExample1.main(ImmutableExample1.java:21)
map.put(1,3);
}
}
- Guava:Immutablexxx
源码
// ImmutableList
public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11);
}
// 超过12个元素,则声明为一个数组
public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12, E... others) {
Object[] array = new Object[12 + others.length];
array[0] = e1;
array[1] = e2;
array[2] = e3;
array[3] = e4;
array[4] = e5;
array[5] = e6;
array[6] = e7;
array[7] = e8;
array[8] = e9;
array[9] = e10;
array[10] = e11;
array[11] = e12;
System.arraycopy(others, 0, array, 12, others.length);
return construct(array);
}
private static <E> ImmutableList<E> construct(Object... elements) {
for(int i = 0; i < elements.length; ++i) {
ObjectArrays.checkElementNotNull(elements[i], i);
}
return new RegularImmutableList(elements);
}
实例
@ThreadSafe
public class ImmutableExample2 {
private final static List<Integer> list = ImmutableList.of(1,2,3);
private final static ImmutableSet set = ImmutableSet.copyOf(list);
// 奇数位参数为key,偶数位参数为value
private final static ImmutableMap map1 = ImmutableMap.of(1,2,3,5);
private final static ImmutableMap<Integer,Integer> map2 = ImmutableMap.<Integer,Integer>builder()
.put(1,2).put(3,4).build();
public static void main(String[] args) {
// 执行都会跑出 UnsupportedOperationException异常
// 但是使用ImmutableXXX声明会直接在编译的时候就告诉你这个方法已经被废弃
list.add(5);
set.add(6);
map1.put(1,2);
map2.put(3,4);
}
}
作者:Meet相识_bfa5
链接:https://www.jianshu.com/p/7a7f13f091bc
來源:简书