概要
Java 標準の Arrays#asList について述べます。
Arrays#asList とは
配列あるいは可変長引数を List に変換するメソッドです。このメソッドで作られる List は unmodifiable です。add や remove を使うと UnsupportedOperationException が発生し、最悪プログラムが終了します。
実装を覗く
実際にはどういう実装になっているのかを GrepCode で見てみましょう。
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
あれ、これだったら特に問題なく modifiable な List が取得できるのではないでしょうか?
実はこの ArrayList というのは、java.util.ArrayList ではありません。上記メソッドのすぐ下を見てみましょう。
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);
}
何でしょうかこのクラスは……紛らわしいから標準クラスと同じ名前付けないでほしいですね。
この Arrays#ArrayList は add も remove も Override していないので、それらのメソッドをコールすると super クラス(AbstractList)のメソッドが呼ばれて UnsupportedOperationException が発生します。
(参考) AbstractList の実装の一部
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
備考
Modifiable な List の初期化に使いたい場合は下記の通り書けばよいです。
List<String> toList = new ArrayList<>(Arrays.asList("Apple", "Bacon", "Chocolate"));
Arrays#asList を使わない場合はこういう書き方もあります。ただ、チェックスタイルの設定次第では警告が表示されます。
List<String> toList = new ArrayList<>(){{add("Apple"); add("Bacon"); add("Chocolate");}};
Eclipse Collections の Lists を使うと、このように書けます。
List<String> ofList = Lists.immutable.of("Apple", "Bacon", "Chocolate");