Arrays.asList 使用细节
Posted weixiaotao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Arrays.asList 使用细节相关的知识,希望对你有一定的参考价值。
通常初始化后使用如下,但是报错 UnsupportOperationException....
根据提示信息,就是调用add()方法时抛出了异常。顺着堆栈信息往上找,提示的是AbstractList类的108行出了异常,这一行所在方法的具体实现如下:
//108行 public boolean add(E var1) this.add(this.size(), var1); return true; //148行 public void add(int var1, E var2) throw new UnsupportedOperationException(); //下面看下Arrays.asList的具体实现 @SafeVarargs public static <T> List<T> asList(T... var0) return new Arrays.ArrayList(var0); //Arrays.ArrayList 实现 private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, Serializable private static final long serialVersionUID = -2764017481108945198L; private final E[] a; //关键 ArrayList(E[] var1) this.a = (Object[])Objects.requireNonNull(var1); public int size() return this.a.length; public Object[] toArray() return (Object[])this.a.clone(); public <T> T[] toArray(T[] var1) int var2 = this.size(); if (var1.length < var2) return Arrays.copyOf(this.a, var2, var1.getClass()); else System.arraycopy(this.a, 0, var1, 0, var2); if (var1.length > var2) var1[var2] = null; return var1; public E get(int var1) return this.a[var1]; public E set(int var1, E var2) Object var3 = this.a[var1]; this.a[var1] = var2; return var3; public int indexOf(Object var1) Object[] var2 = this.a; int var3; if (var1 == null) for(var3 = 0; var3 < var2.length; ++var3) if (var2[var3] == null) return var3; else for(var3 = 0; var3 < var2.length; ++var3) if (var1.equals(var2[var3])) return var3; return -1; public boolean contains(Object var1) return this.indexOf(var1) != -1; public Spliterator<E> spliterator() return Spliterators.spliterator(this.a, 16); public void forEach(Consumer<? super E> var1) Objects.requireNonNull(var1); Object[] var2 = this.a; int var3 = var2.length; for(int var4 = 0; var4 < var3; ++var4) Object var5 = var2[var4]; var1.accept(var5); public void replaceAll(UnaryOperator<E> var1) Objects.requireNonNull(var1); Object[] var2 = this.a; for(int var3 = 0; var3 < var2.length; ++var3) var2[var3] = var1.apply(var2[var3]); public void sort(Comparator<? super E> var1) Arrays.sort(this.a, var1); //此处可以发现,改内部类继承了 AbstractList 但是却没有实现其的add,remove等方法。(下面给出AbstractList 的定义) public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> protected transient int modCount = 0; protected AbstractList() public boolean add(E var1) this.add(this.size(), var1); return true; public abstract E get(int var1); public E set(int var1, E var2) throw new UnsupportedOperationException(); public void add(int var1, E var2) throw new UnsupportedOperationException(); public E remove(int var1) throw new UnsupportedOperationException(); .......
最后,我们发现,此ArrayList不是彼ArrayList。这个ArrayList是Arrays工具类中实现的内部静态类,我们可以发现,这个类集成了AbstractList类,但是并没有重写add()方法,所以在我们的示例代码标记(2)处调用add()方法时,实际是调用父类AbstractList的add()方法,这也就回到了开头分析的那两个add()方法了,它们都没有具体实现,只会抛出UnsupportedOperationException。
结论总结:
我们调用Arrays的asList()方法将数组转换成List时返回的是Arrays的静态内部类ArrayList,它自身并未重写add()方法,而其父类AbstractList实现的add()方法只会抛出UnsupportedOperationException,导致我们调用Arrays的静态内部类ArrayList的add()方法时,实际调用的是只会抛出UnsupportedOperationException的AbstractList的add()方法,这就是异常出现的原因了。
解决办法
4、 解决方案
可以自己写个工具类转换方法,可以参考一下代码:
private static <E> List<E> transferArrayList(E[] array) List<E> transferedList = new ArrayList<>(); Arrays.stream(array).forEach(arr -> transferedList.add(arr)); return transferedList;
以上是关于Arrays.asList 使用细节的主要内容,如果未能解决你的问题,请参考以下文章