web-dev-qa-db-ja.com

型の安全性:オブジェクトからの未チェックのキャスト

アクションクラスにオブジェクトをキャストしようとしましたが、警告が表示されます。

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();
 }
 [...]

助けてくれてありがとう

39
Matthew

はい-これは type erasure の自然な結果です。 oが実際にキャストによってキャッチされないAction<String>のインスタンスである場合、使用しようとしたときにのみ問題が表示され、代わりにClientInterfaceを渡す文字列。

以下を使用して警告を取り除くことができます:

@SuppressWarnings("unchecked")

関数の注釈としてですが、根本的な問題を簡単に整理することはできません:(

62
Jon Skeet

いつものように、ジョン・スキートは正しい。

彼の答えの簡単ではない部分について詳しく説明するには:

与えられた

class ClientAction implements Action<ClientInterface> {}

あなたは書ける:

Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();

これにより、キャストと警告の両方が排除されますが、非ジェネリック型を導入する代わりに、.class十分に正確に入力されたClassオブジェクトを取得します。

15
meriton

警告は、実行時にキャストが正常に機能する場合でも、コンパイラが型の安全性を保証できないことを意味します。消去のため、実行時のキャストは単にアクションへのキャストです。基礎となるジェネリッククラスが予想どおりClientInterfaceタイプではない可能性があります。この場合、問題はClassCastExceptionとして後で表示されます(それよりずっと後のこともあります)。

この特定のケースでは、次のコンパイラ指令によってこの特定の警告を抑制することをお勧めします。

@SuppressWarnings("unchecked")
6
Eyal Schneider

心配しないでください。これは、Javaコンパイラがオブジェクトの実際のタイプを知る方法がないためです。

2
Petar Minchev

消去(つまり、パラメーター化された型が消去された)のために型情報を失ったため、警告が表示されます。ジェネリックがより頻繁に使用されるように周囲のコードをクリーンアップする以外は何もできません。したがって、ジェネリック型情報を渡すことができ、キャストをまったく回避できます。

1
Chris Dennett