android スレッドセーフはじめの一歩(3)

不変なものはスレッドセーフということで、unmodifiableList、ImmutableListについて説明します。

Collections.unmodifiableList

Map用のCollections.unmodifiableMap、Set用のCollections.unmodifiableSet、もあります。

クラス内で定数的に使うListがあります。コンストラクタや初期化メソッドで、要素を追加した後は、要素数は変化しないListです。

List<String> names = new ArrayList<String>();
names.add("X");
names.add("Y");
names.add("Z");Code language: JavaScript (javascript)

Collections.unmodifiableListでラップしたListに、setやadd、removeすると、UnsupportedOperationExceptionが発生します。自分自身のうっかりでlistの変更を防ぐことができます。

初期の開発者と後々の開発者が違う場合でも、Collections.unmodifiableListでラップすることで、「このListは変更禁止ですよ」というメッセージを伝えることができます。

List<String> list = new ArrayList<String>();
list.add("X");
list.add("Y");
list.add("Z");
list = Collections.unmodifiableList(list);

list.set(0, "CHANGE");  // UnsupportedOperationExceptionが発生

list.add("MORE"); // UnsupportedOperationExceptionが発生

list.remove(0); // UnsupportedOperationExceptionが発生
Code language: PHP (php)

ただし、要素のオブジェクトのメンバー変数は変更できます。要素のオブジェクトがスレッドセーフかどうかは、別の問題です。

unmodifiableListでラップしたからといって、要素のオブジェクトはスレッドセーフにはなりませんので、過信しないようにしてください。

ImmutableList

unmodifiableListは、addやremoveの実行時にUnsupportedOperationExceptionが発生しますが、コンパイル時にはわかりません。

org.eclipse.collectionsのImmutableListは、addメソッどやremoveメソッド自体がないので、うっかりaddを書いても、すぐに間違いに気づきます。

タイトルとURLをコピーしました