3

好奇心から:私はSSCCEをフォローしています

import javax.ws.rs.Path;

    @Path("/")
       public class T {

        void a() {

            Path p = getClass().getAnnotation(Path.class); //1

            Class z = getClass();
            p = z.getAnnotation(Path.class); //2
        }
}

コンパイラは次のエラー メッセージを表示します。

T.java:12: incompatible types
found   : java.lang.annotation.Annotation
required: javax.ws.rs.Path
        p = z.getAnnotation(Path.class); 
Note: T.java uses unchecked or unsafe operations.

//1 行と //2 行の違いは何ですか?

4

1 に答える 1

4

これは raw 型の奇妙な機能です。ジェネリック型 ( Class<T>) を生の型( ) として使用するClassと、そのメンバーは消去として扱われます。

JLS §4.8 生の型:

コンストラクター (§8.8)、インスタンス メソッド (§8.8、§9.4)、または非静的フィールド (§8.3) の型 M スーパークラスまたはスーパーインターフェイスから継承されていない生の型 C は、その型の消去ですC に対応するジェネリック宣言で。

事実上、生の型を使用すると、そのメンバーの宣言でジェネリック関連のものはすべて無効になります。

あなたの場合、Class<T>宣言された方法

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

その消去に変わります

public Annotation getAnnotation(Class annotationClass) 

Annotationtoの割り当てが原因でエラーが発生しますPath

これを防ぐには、ジェネリック型をパラメーター化された形式で使用する必要があります。Tinの実際の値を気にしない場合はClass<T>、ワイルドカードを使用します。

void b(Class<?> z) {
    Path p = z.getAnnotation(Path.class); 
}   
于 2012-04-17T15:13:48.973 に答える