プログラムを書いていると、enum class をキーとして、何らかの値を保持する Map
を作ることがよくある。
key としてすべての enum を網羅していた場合、Map#get
が null を返すことはないはずなのだが、戻り値は nullable であるため、checkNotNull
を挟むなどしなければならないのが面倒。
そこで、すべての enum を網羅していることを前提に、non-nullable な Map#get
ができる仕組みを考えてみた。
基本的には enumMap
に処理を移譲しつつ、Map#get
の戻り値を non-nullable にしている。構築時にすべての enum を網羅していることを確認済みなので、Map#get
したタイミングで例外が飛ぶことはない。
まあ、checkNotNull
を wrap しただけといえばそうなのだが。
map
を使う側では checkNotNull
を使うことなく non-nullable な値を取得できる。Map
の実装としてもそのまま使える。
これで Map#get
については解決できたが、これだと enum を網羅していないことを実行時にしか検知できないのが惜しい。ぜひともコンパイル時に解決したいところ。
そこで考えたのが以下のコード。
まず、各要素の key となる enum に対して値を決めさせるインターフェイスにすることで、強制的にすべての enum を key に持つ Map
しか作れないようにした。値を決める部分は利用者次第だが、なにか共通の規則で導出するのでなければ、when
式が使える。when
式はすべての分岐を網羅していない場合にコンパイルエラーになるので、コンパイルが通っていれば記述に漏れがないことが確定し、実行時エラーの可能性を排除できる。
実用するかはともかくとして、イメージしたものを作れて満足した。