
在实际项目开发中,有时候需要方法返回不可修改的集合或对象,比如:Map。
如以下例子:
1 | /** 缓存的 Map */ |
cachedMap
作为私有对象,使得只有通过 getCachedMap()
方法获取缓存的 Map。
但是由于返回的是引用,其它调用到的地方获取到返回的 Map 后还是可以对其进行修改,这不符合闭合原则。我们希望返回的是副本或通过某种办法让其不能修改。
在 java.util 包中的 Collections 类有个 unmodifiableMap 方法,可以简单的解决上述问题,查看其源码:
1 | public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) { |
可以发现,unmodifiableMap 方法返回的是一个 UnmodifiableMap 包装类。这个类里面保存了一个 Map 成员属性 m。同时这个类也实现了 Map 接口,说明它具有 Map 的所有特性。
- 当调用其读相关方法(size、isEmpty、get)时,间接调用的是成员属性 m 的对应方法。
- 当调用其修改相关方法(put、remove、clear)时,直接抛出
UnsupportedOperationException
异常,不让修改。
所以,Collections.unmodifiableMap()方法通过返回一个 UnmodifiableMap 包装类实现返回的 Map 不可修改,其原理简单、调用方便。
但还需要注意的是:如果 Map 的 value 是对象类型的话,如:Map<String, User>
,虽然 User 本身引用不能修改,但是可以通过拿到 User 引用修改 User 内部数据。
同理:Collections 除了 unmodifiableMap,还有 unmodifiableCollection、unmodifiableList、unmodifiableSet 等方法,其原理是类似的: