Java 8为ElementType枚举增加了TYPE_PARAMETER和TYPE_USE两个枚举值。这样就允许定义注解时使用@Target(ElementType.TYPE_USE)修饰,这种注解就是类型注解。
在Java 8以前,注解只能在定义程序元素的时候使用。从Java 8开始,类型注解可以在任何使用类型的地方使用。例如如下位置 :
- 创建对象
- 类型转换
- 使用implements实现接口
- 使用throws 声明抛出异常
上面这些位置都会使用到类型,因此可以使用类型注解来修饰。
TYPE_PARAMETER
直译为类型变量,被该值所修饰,意味着声明的注解可以作用在泛型类,泛型接口,泛型方法上。
示例代码
//声明注解
// 声明注解
@Target({ ElementType.TYPE_PARAMETER})
public @interface NotNull {}
//测试注解
public class TestNotNull<@NotNull T> {
public <@NotNull T> void testT(T x) {}
}
public interface A<@NotNull T> {}
TYPE_USE
示例代码
// 声明类型注解
@Target(ElementType.TYPE_USE)
public @interface NotNull {}
使用类型注解
@NotNull // 声明类使用类型注解,在继承和实现的时候都使用类型注解
public class TestNotNull<@NotNull T> extends @NotNull HashMap<String, String> implements @NotNull Serializable {
@NotNull
private T t;
// 声明成员变量使用类型注解
@NotNull
private String test;
// 方法中使用类型注解,抛异常使用类型注解
public static void main(@NotNull String[] args) throws @NotNull Exception {
// 声明局部变量使用类型注解
@NotNull
String string;
// 创建对象使用类型注解
string = new @NotNull String("小钻风");
// 强制类型转换使用类型注解
Object object = (@NotNull Object) string;
System.out.println(object);
}
@NotNull // 声明方法使用类型注解, 泛型使用类型注解
public String test(List<@NotNull String> lists) {
return "";
}
// @NotNull 返回值为空意味着没有类型返回,所以不能够使用类型注解
public void test2() {}
public <@NotNull T> void testT(@NotNull T xddf) {
}
}
注意
在疯狂Java讲义一书中只明确提出了使用TYPE_USE的才是类型注解,并没有提到使用TYPE_PARAMETER也是类型注解,也没有否认使用TYPE_PARAMETER不是类型注解。有任何问题,欢迎提出。
类型变量一词来源于《Java核心技术 卷I》基础知识 (原书第9版) Cay S. Horstmann Gary Cornell 著 机械工业出版社