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ドキュメントも問題だと思いました。