2012-02-24 8 views
20

私はJava 1.6.0_25を使用しています。なぜClass.getAnnotation()はキャストを要求しますか?

私は注釈が定義されている:

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Resource { 
    String value(); 
} 

以降、私はgetAnnotationを使用する場合:

Resource resource = (Resource)cls.getAnnotation(Resource.class); 

コンパイラとIDEは私が結果をキャストしなければならないことを同意するが、getAnnotationはJavaで宣言されています1.5文書の内容:

public <A extends Annotation> A getAnnotation(Class<A> annotationClass); 

Resource.classはClassタイプなので、これは、cls.getAnnotation(Resource.class)がResource型を返さなければならないことを意味し、キャストする必要があります。

私がgetAnnotationを使って見つけたすべての例はキャストを持っていないので、何か間違っている必要があります。

答えて

24

clsの種類は何ですか?それは生のClassですか、それともClass<Something>ですか?

生のタイプClassの場合は、キャストが必要です。 Classの代わりに少なくともClass<?>にすると、もうキャストする必要はありません。

Class cls = Example.class; 

// Error: Type mismatch, cannot convert from Annotation to Resource 
Resource anno = cls.getAnnotation(Resource.class); 

Class<?> cls2 = Example.class; 
Resource anno = cls2.getAnnotation(Resource.class); // OK 

Class<Example> cls3 = Example.class; 
Resource anno = cls3.getAnnotation(Resource.class); // OK 
+1

これはうまくいきますが、最初の行がコンパイルされないのはなぜですか? getAnnotationメソッドはTのTを全く使用しないので、何の違いもありません。 (それは明らかです!!) – assylias

+1

生のクラス 'Class'を使用すると、コンパイラは、ジェネリック以前のJavaとの下位互換性のために、クラス内のすべてのジェネリックについて忘れてしまいます。 – Jesper

+1

間違いなく働いた。奇妙だと思われますが、@Jesperはそれが後方互換性のために正しいと思います。 –

関連する問題