generics で SuppressWarnings を使う
generics を使っていると、コンパイル時に色々な警告に遭遇します。
原則これらは簡単に除去できるんですが、中にはどうやるの?というケースもあります。
今回は、そういう特殊なケースについて記述します。
特殊な警告例
次のコードは、java.lang.List#get(int) と同じことを、無理やりメソッドにしたものです。
わざとらしく、List#toArray() とかを使っています。
public staticE get(List list, int offset) { // エラーチェックロジックは省略 E array = (E) list.toArray(); return array[offset]; }
これをコンパイルすると、次の警告が出てきます。
型の安全性:Object から E へのキャストは、実際に消去された型 Object[] に対してチェックを行います。
警告の意味
generics の型チェックは、コンパイル時にのみ行います。
この型チェックの情報は、実行時には無くなってしまうという仕様になっています。
(「コンパイル時にチェックしているから十分でしょ」ということのようです。)
そのため、「”(E) list.toArray()”なんて書いているけれども、実際には Object が返されるよ、大丈夫!?」という意味の警告を、コンパイル時に出してくれているのです。
解決策
ことこのメソッドに関しては、引数が List
なので、この警告は余計なおせっかいということになります。
そういう場合には、@SuppressWarning("unchecked") を使います。
// 型が E であることが保障されている。 public staticE get(List list, int offset) { // エラーチェックロジックは省略 @SuppressWarnings("unchecked") E array = (E) list.toArray(); return array[offset]; }
SuppressWarnings の使いどころ
@SuppressWarnings("unchecked") は、generics の型チェックをある程度無効にする意味があるので、多用すると generics の効用を損なってしまいます。
なので、SuppressWarning は、以下のように使用しましょう。
- コード上型の安全性が保障できる場合にのみ使用する。
- 必要最小限のスコープで使用する。(メソッド全体、クラス全体での定義は避ける)
以下のようには定義しないようにしましょう。
@SuppressWarnings("unchecked") public staticE get(List list, int offset) { // エラーチェックロジックは省略 E array = (E) list.toArray(); return array[offset]; }