basyura's blog

あしたになったらほんきだす。

Arrays.asList で作った List には add できない

あまり使った事無いけど便利だよなぁ、ぐらいにしか思ってなかったんだけど久々に PG してたらタイトルの通りでびっくりした。

import java.util.*;
public class ArraysTest {
	public static void main(String args[]) {
		String[] array = {"1","2","3"};
		List list = Arrays.asList(array);
		list.add("4");
	}
}

これを実行する。

$ java ArraysTest
Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:131)
        at java.util.AbstractList.add(AbstractList.java:91)
        at ArraysTest.main(ArraysTest.java:6)

JavaDoc に UnsupportedOperationException の事なんて書いてないし追加できないとも書いてないから(書いてないことはない)意味が分からずソース(jdk 1.5)を見てみた。

public static <T> List<T> asList(T... a) {
  return new ArrayList<T>(a);
}

ArrayList が生成されてるのになんで?と混乱したんだけど、Arrays のソースをよく見てみると

private static class ArrayList<E> extends AbstractList<E>
  implements RandomAccess, java.io.Serializable
{

と定義してある・・・んで add が実装されていないので AbstractList#add が呼ばれるんだけど、AbstractList#add を見ると

public boolean add(E o) {
  add(size(), o);
  return true;
}
public void add(int index, E element) {
  throw new UnsupportedOperationException();
}

となっているので UnsupportedOperationException が投げられる。