アクションクラスにオブジェクトをキャストしようとしましたが、警告が表示されます。
Type safety: Unchecked cast from Object to Action<ClientInterface>
Action<ClientInterface> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<ClientInterface>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
助けてくれてありがとう
はい-これは type erasure の自然な結果です。 o
が実際にキャストによってキャッチされないAction<String>
のインスタンスである場合、使用しようとしたときにのみ問題が表示され、代わりにClientInterface
を渡す文字列。
以下を使用して警告を取り除くことができます:
@SuppressWarnings("unchecked")
関数の注釈としてですが、根本的な問題を簡単に整理することはできません:(
いつものように、ジョン・スキートは正しい。
彼の答えの簡単ではない部分について詳しく説明するには:
与えられた
class ClientAction implements Action<ClientInterface> {}
あなたは書ける:
Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();
これにより、キャストと警告の両方が排除されますが、非ジェネリック型を導入する代わりに、.class
十分に正確に入力されたClass
オブジェクトを取得します。
警告は、実行時にキャストが正常に機能する場合でも、コンパイラが型の安全性を保証できないことを意味します。消去のため、実行時のキャストは単にアクションへのキャストです。基礎となるジェネリッククラスが予想どおりClientInterfaceタイプではない可能性があります。この場合、問題はClassCastExceptionとして後で表示されます(それよりずっと後のこともあります)。
この特定のケースでは、次のコンパイラ指令によってこの特定の警告を抑制することをお勧めします。
@SuppressWarnings("unchecked")
心配しないでください。これは、Javaコンパイラがオブジェクトの実際のタイプを知る方法がないためです。
消去(つまり、パラメーター化された型が消去された)のために型情報を失ったため、警告が表示されます。ジェネリックがより頻繁に使用されるように周囲のコードをクリーンアップする以外は何もできません。したがって、ジェネリック型情報を渡すことができ、キャストをまったく回避できます。