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

这是原始类型的一个奇怪特征。当您使用泛型类型 ( Class<T>) 作为原始类型 ( Class) 时,其成员被视为它们的擦除。

JLS §4.8 原始类型

未从其超类或超接口继承的原始类型 C 的构造函数(第 8.8 节)、实例方法(第 8.8 节、第 9.4 节)或非静态字段(第 8.3 节)M 的类型是其类型的擦除在对应于 C 的泛型声明中。

实际上,使用原始类型会在其成员的声明中禁用所有与泛型相关的东西。

在您的情况下,方法Class<T>声明为

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

变成它的擦除

public Annotation getAnnotation(Class annotationClass) 

Annotation你得到一个由to的分配引起的错误Path

为了防止它,您需要在其参数化形式中使用泛型类型。如果您不关心 in 的实际值T,请Class<T>使用通配符:

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