likes
comments
collection
share

为什么返回的List进行add操作竟然报错?

作者站长头像
站长
· 阅读数 19

为什么返回的List进行add操作竟然报错?

public class Test {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        list.add(5);
    }
}

为什么返回的List进行add操作竟然报错?

这一瞬间我开始相信了玄学,清idea缓存、重启项目、重启系统。竟然还是不行,又一个开发开始怀疑人生了....

短暂失意后,秉着科学严谨的态度,开始看起了源码。

首先我们看起了这个异常是什么意思。

为什么返回的List进行add操作竟然报错?

Thrown to indicate that the requested operation is not supported.表示不支持这个操作,为什么add操作会不支持呢?

我们查看这个Arrays.asList()方法

为什么返回的List进行add操作竟然报错?

这里是返回了一个ArrayList对象。ArrayList对象为啥不能add操作,感觉自己的体系开始崩塌。怀疑自己之前用的是什么。为了验证我们继续点击这个ArrayList。

为什么返回的List进行add操作竟然报错? 瞬间恍然大悟,原来这个ArrayList并不是我们之前用的java.util.ArrayList而是java.util.Arrays.ArrayList是Arrays下的一个内部类。它通用继承了AbstractList但是没有重写add方法只是实现了其他的方法,所以add就会抛出异常UnsupportedOperationException

为什么返回的List进行add操作竟然报错?

为什么返回的List进行add操作竟然报错? 当子类实例指向父类引用时,是子类决定了父类引用调用谁的成员方法。

  • 如果子类重写了父类的方法,父类引用会优先调用子类重写的方法
  • 如果子类没有重写父类的方法,父类引用会调用自己的方法 当子类实例指向子类引用时,子类引用优先调用子类的方法,如果子类没有此方法,则会调用父类的方法

由于它继承了AbstractList,AbstractList实现了List。所以可以用List来接收,又因为返回的实例对象又名叫ArrayList,但此ArrayList又非彼ArrayList,所以会让我们误解迷惑。

同样的例子还有Collections.emptyList();它返回的是一个java.util.Collections.EmptyList对象。该对象同样没有实现add方法。

为什么返回的List进行add操作竟然报错?

同样该类的EmptySetEmptyList也是没有实现相关的添加操作方法。

结论

相信科学,拒绝玄学(狗头)

  1. 返回的List实例对象并不是我们所认为的ArrayList对象。
  2. 该对象是一个内部类并没有提供add方法。
  3. 需要返回一个可以add操作的List方法时要慎用此类方法。如果只是遍历获取可以使用。