Arrays.asList(어레이)
는 String[]
등의 배열을 List
리스트로 바꿀 때 매우 자주 쓰던 메소드였습니다.
그런데 어느날 이렇게 짜고 나니 오류가 빠방!!!
// 사진 url 배열을 리스트로 만들고 List<String> photoList = Arrays.asList(photoUrls); // 해당 리스트에 또 다른 사진들을 추가 arrayList 형태 List<String> photoList2 = getPhotoList(); photoList.addAll(photoList2); // java.lang.UnsupportedOperationException
java.lang.UnsupportedOperationException
은 자주 못보던 오류라 열심히 찾아봤더니, 문제는 Arrays.asList()
method 의 결과물은 우리가 흔히 쓰는 java.util.ArrayList
가 아니라 Arrays
안에 있는 inner class 였습니다.
Arrays$arrayList
/** * @serial include */ private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } @Override public int size() { return a.length; } @Override public Object[] toArray() { return a.clone(); } @Override @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } /*** 중략 ***/ @Override public void sort(Comparator<? super E> c) { Arrays.sort(a, c); } }
위 코드를 보시면 알 수 있듯이, abstractList 를 상속받아서 생성되었고 딱히 list 에 있는 add
나 addAll
method 를 override 하지 않고 있습니다. 그렇기에 결국 해당 addAll(컬렉션)
을 사용하면 AbstractCollection
의 addAll
메소드가 수행되게 됩니다. ( AbstractList
에 addAll(collection) 메소드가 없기때문에 상속받은 AbstractCollection
것을 수행)
/** AbstractCollection class 발췌 **/ public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) // abstractList 의 add 사용 modified = true; return modified; } /** AbstractCollection class 발췌 **/ // 일반적인 add 메소드는 가능 public boolean add(E e) { **add(size(), e);** // 아래 add(index,element) 호출 return true; } // 오류남... 결국 add(index,element) 를 재구현 하지 않으면 죄다 못쓰는 메소드 public void add(int index, E element) { throw new UnsupportedOperationException(); }
위와 같은 addAll
메소드를 그대로 사용하다보니 처음에 제가 addAll
하게 된 부분에서 UnsupportedOperationException
가 나오게 된 것입니다. 파라미터에 인덱스가 있는 add
를 Override 해야지만 addAll
도 쓸 수 있게 되는 상태로 보이는데, Arrays.asList
의 결과인 Arrays$arrayList
클래스는 굳이 그렇게 만들지 않았기에 오류가 나네요.
결론
Arrays.asList(배열)
의 결과인 arrayList
는 기존의java.util.ArrayList
와는 다르며, addAll
메소드를 쓸 수 없는 상태다… 라고 알아 두면 될것 같습니다.
아무튼 이렇게 또 하나 배우게 되는 하루였습니다. 닮았지만 부족한 녀석을 주의하세요.