総称型の未検査キャスト
JDK 5.0 / JRE 5.0 | Generics | Eclipse 3.3.2 |
Javaコンパイラ による未検査キャストの警告
Javaコンパイラ によるチェックと未検査キャスト
Java 5.0 で総称が取り込まれてから、Object型から総称型(List<String>など)へのキャストなどは「型の安全性に問題がある(キャストに失敗する可能性がある)」という理由でコンパイラが未検査キャストの警告を出してきます。例えば、 ObjectInputStream#readObject()の呼び出しのように Object 型で値を受け取った後、想定したクラスにキャストして使用するというケースが該当します。
ただ、この実装では Object型 からのキャストをするしかなく、警告を出さないで実装することはできないと思います。その度にわかっていながら警告を表示させるのでは肝心な警告を見逃す危険性が高くなり好ましくないと思います。
未検査キャスト警告の回避
この警告は Java コンパイラが出力するもので、メソッド名の前に『@SuppressWarnings("unchecked")』とつけることで、コンパイラにそのメソッドの警告をチェックさせなくすることができます。これは Java 5.0 から実装されたアノテーションという仕組みを利用した Javaコンパイラ の動作です。
このようにアノテーションでチェックしないことを明示するか、コンパイラの設定自体で未検査キャストのチェックを実施しないようにすることでも対応できます。しかしこれらの方法では、メソッド内の全ての警告がチェックされなくなってしまったり、未検査キャストを全くチェックしなくなってしまったりと、それ以外の警告が発見できなくなってしまい逆効果となりかねません。
戻り値の型に合わせてキャストする
キャスト部分のみをメソッド化
Javaコンパイラによる警告チェックを行わない箇所を最小限にするため、キャストのみを行うメソッドを実装してそこに『@SuppressWarnings("unchecked")』を定義することにしました。総称(Generics)を使用すると、呼び出し元が受け取る型に合わせてキャストをするということができます。
@SuppressWarnings("unchecked") |
public static <T> T automaticCast(Object src) { |
T castedObject = (T) src; |
return castedObject; |
} |
呼び出し元では List<String> list = automaticCast(objectData);
のように書けば List<String> へのキャストが行われ、String str = automaticCast(objectData);
のように書けば String へのキャストが行われます。
メソッド自体はキャストしか行っていないので『@SuppressWarnings("unchecked")』をつけても影響はなく、呼び出し元でも具体的にキャストする型を記述しなくなりますが、戻り値の型は具体的に宣言しているわけですし問題ないと思います。