リストをadd/removeできないようにするためにCollections.unmodifiableListを使うことで、
読取り専用リストとして取得することができるが、以下の注意点が必要なのでメモ。
引数にnullを渡すとヌルポが発生する
final List<String> nullList = Collections.unmodifiableList( null );
上のコードを実行すると、「NullPointerExceptionが」発生する。
リストを取得するなんらかのメソッドを読取り専用リストにしようとして、その返却値がnullだった場合によく起る。
これを防ぐには事前にnullチェックをしてあげるか、nullチェックを行いnullの時はCollections.emptyList()を返しそれ以外はunmodifiableListで包んで返却してあげる自作メソッドなどを作る。
読取り専用としたら二度と変更することはできない
final List<String> list = Collections.unmodifiableList( new ArrayList<String>() );
final List<String> modifilist = (ArrayList<String>) list;
読取り専用にしたリストをキャストで外したりはできない。
上のコードではキャストした時点で「ClassCastException」が発生する。
※もし外すことができてしまったらそもそも読み取り専用としての意味がないので、そういうコーディングはしない方がいいと思う。
※そもそも外したりできるの・・?
読取り専用としたリストをaddして使いたい場合(new)
final List<String> list = Collections.unmodifiableList( new ArrayList<String>() );
// list.add( "TEST1" ); ←これはできない!
final List<String> modifilist = new ArrayList<String>( list );
modifilist.add( "TEST2" ); // ←これはできる!
こうすることでmodifilistにaddできるようになる。しかし、newしているため参照先が変わる(modifilistでaddした内容はlistには反映されない)
読取り専用とした後で使いたい場合
final List<String> list = new ArrayList<String>();
final List<String> readOnlylist = Collections.unmodifiableList( list );
list.add( "TEST1" ); // readOnlylistの中身も反映される
このように通常のlistと読取り専用リストの変数に分ける。
こうすればlistでaddした内容をreadOnlylistでも見ることができる(メソッドの中ではlistを使い、外に渡すときはreadOnlylistを渡すなど・・)
unmodifiableListは他のモジュールから貰ったリストを内部では読取り専用にしておいたり、
書き換えて欲しくないリストを外に渡すときに読取り専用にしておいたりかなり使えるのでオススメ。