3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

java.utilにはArrayListクラスが二つある

Posted at

#導入
こんにちは。けちょんです。
皆さん、ArrayList使ってますか?
もちろん私もよく使います。
1つ予想外なことがあったので紹介します。

#クイズ
以下ソースで実行時例外が発生します。
それはどこでしょう。

String[] array = { "banana", "apple", "melon" }; // 配列を作成
List<String> list1 = Arrays.asList(array); // 配列からリストの作成

List<String> list2 = new ArrayList<>();
list1.stream().forEach(e -> list2.add(e)); // list1と同じ要素を持つリストを作成

list1.add("lemon"); // list1に追加
list2.add("lemon"); // list2に追加

System.out.print(list1); // list1の結果を出力
System.out.print(list2); // list2の結果を出力

※streamに不慣れな方に言っておくと、streamの行ではありません。










正解は、list1.add("lemon")です!
以下例外が発生します。

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.AbstractList.add(AbstractList.java:153)
	at java.base/java.util.AbstractList.add(AbstractList.java:111)
	at Main2.main(Main2.java:44)

ちなみにlist2.add("lemon")は正常に実行されます。

#なぜ例外が発生する?

##まず、それぞれクラスを見てみましょう

System.out.println(list1.getClass()); // class java.util.Arrays$ArrayList
System.out.println(list2.getClass()); // class java.util.ArrayList

どちらもArrayListです。
が、list1はArraysクラスの内部クラスのArrayListです

つまり、ArrayListクラスは二つあるのです。(どや)

##java.util.Arrays$ArrayListの中身は?

Arraysの中を覗いてみましょう。
長いので書ききれませんが、クラス名の宣言はこのようになっています。

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

内部クラスで定義されていますね。
そして、ArrayListの中ではaddメソッドは実装されていません。

そのため、親クラスのAbstractListを見に行きます。(エラーメッセージで出力されていたクラスですね)

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

犯人はこいつですね!!
呼び出すとUnsupportedOperationExceptionを投げるように実装されています。

##なぜこんな実装に、、、
AbstractListは文字通りabstractクラスであるため、実装前提のクラスです。
そのため、継承せずに呼び出すと例外を投げるよう実装しているようです。

いや、インターフェースにするなり、asListメソッドの実装を変えたり、やりようがある気はしますが、、、
詳しい人教えてください、、、

#まとめ
java.utilには、以下二つのArrayListが存在する
class java.util.Arrays$ArrayList
class java.util.ArrayList

①はaddメソッドを呼び出すと例外が発生するので要注意

3
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?