UnsupportedOperationExceptionが発生するので、逆コンパイルしたらunmodifiableだった
JavaのUnsupportedOperationExceptionの話です。
先日、とあるAPI経由で受け取ったSetを変更しようと思いました。
public void something(HogeClass hoge){
Set<Fuga> set = hoge.getFugas();
set.clear();
}
以下の例外が発生しました。EclipseのPluginだったのでスタックトレースが完全に出力されず・・・。以下のようなしょぼいメッセージだけでした。
Unexpected error while running Piyo java.lang.UnsupportedOperationException
なんでなんだ・・・。少し考えて自分の知識と経験から以下のいずれかだろうなーと推測しました。
- 受け取ったSetが特殊でclearをサポート外としている。つまり、clear内でthrow new UnsupportedOperationExceptionをしている。
- 変更不可能なSet
上記のgetFugas()メソッドの中を見ると原因が分かりました。
/**
* @return Returns the fugas.
*/
public Set<Fuga> getFugas() {
return Collections.unmodifiableSet(fugas);
}
unmodifiableかいっ・・・!
残念です。自分がこのクラスを際どい使い方してるのは承知してますが、それでも折角Javadocコメントが存在するんだから、ちゃんとドキュメント化しておいてほしいというものです。コレクションをコピーして返すか、変更不可として返すかする場合はドキュメント化必須でしょう。
ちなみに今回はスタックトレースが完全に表示されませんでしたが、通常は(コンソールに出力可能な状態では)以下のようなメッセージが表示されます。
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.clear(Collections.java:1094)
at com.tsukaby.sample.Main.main(Main2.java:16)
unmodifiableSetはCollections$UnmodifiableCollectionを返却します。これを知らなかったとしてもスタックトレースから「あれ、Unmodifiable?なんだこれ・・・?HashSetとかじゃないぞ?」ときっかけを得ることくらいはできます。
スタックトレースが全部出ないことも問題ですが、貧弱なAPIドキュメントも問題だと思いました。