深度剖析Java不可变容器(unmodifiable)

本文深入探讨Java中的不可变容器,解释为什么需要它们以及如何实现。不可变容器通过防止意外修改提供安全性,Java的Collections类提供了将其转化为不可变容器的方法。通过分析源码,揭示了如何通过包装可变容器为`Collections.unmodifiable*`实现不可变性,以及它们与一般不可变对象的区别。
摘要由CSDN通过智能技术生成

什么是不可变容器

Java为用户提供了三种常用的容器:ListSetMap,并提供了对容器的各种操作——添加元素,修改元素,删除元素等等。但这几种容器都是可变的(mutable),即容器中的内容是可以改变的。
与可变容器相对的,就是不可变(immutable)容器,immutable意味着一个类的实例中的内容是不可变的,想要改变只能创建一个新的实例。

为什么需要不可变容器

可变性由于能够直接修改容器的内容,操作方便,效率也高,但却带来了很大的安全隐患——容器的内容可能在不经意间被改变,这种不经意的改变可能会给程序的正常运行带来灾难性的后果。考虑到这一点,Java在Collections类中提供了将以上三种容器包装为不可变容器的方法Collections.unmodifiableList(List<? extends T> list)Collections.unmodifiableSet(Set<? extends T> s)Collections.unmodifiableMap(Map<? extends K, ? extends V> m)。以List为例说明如何将可变的容器包装为一个不可变容器

	List<Integer> testList = new ArrayList<>(); // 创建一个新的List
	List<Integer> testUnmodifiableList = Collections.unmodifiableList(testList); // 将可变List包装为不可变List

不可变容器的具体实现

通过阅读源码,我们来进一步了解不可变容器是如何实现的。(以List为例)
首先,Collections类中有一个内部类UnmodifiableCollection,给出其源码

	static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
   
        @java.io.Serial
        private static final long serialVersionUID = 1820017752578914078L;

        @SuppressWarnings("serial") // Conditionally serializable
        final Collection<? extends E> c;

        UnmodifiableCollection(Collection<? extends E> c) {
   
            if (c==null)
                throw new NullPointerException();
            this.c = c;
        }

        public int size()                          {
   return c.size();}
        public boolean isEmpty()                   {
   return c.isEmpty();}
        public boolean contains(Object o)          {
   return c.contains(o);}
        public Object[] toArray()                  {
   return c.toArray();}
        public <T> T[] toArray(T[] a)              {
   return c.toArray(a);}
        public <T> T[] toArray(IntFunction<T[]> f) {
   return c.toArray(f);}
        public String toString()                   {
   return c.toString();}

        public Iterator<E> iterator() {
   
            return new Iterator<E>() {
   
                private final Iterator<? extends E> i = c.iterator();

                public boolean hasNext() {
   return i.hasNext();}
                public E next()          {
   return i.next();}
                public void remove() {
   
                    
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值