要通过method.getannotatedreturntype()获取type_use注解,必须调用annotatedtype的getdeclaredannotationsbytype()或getannotationsbytype(),而非getannotations();注解需声明@target(elementtype.type_use),且仅作用于返回类型位置。

要通过 Method.getAnnotatedReturnType() 获取方法返回值上带有 @Target(ElementType.TYPE_USE) 的注解,关键在于:该方法返回的是 AnnotatedType,而非 AnnotatedElement,所以必须调用其 getAnnotationsByType(...) 或 getDeclaredAnnotationsByType(...) 才能正确提取 TYPE_USE 注解。
确保注解声明为 TYPE_USE
只有目标为 ElementType.TYPE_USE(或包含它的组合,如 ElementType.TYPE_USE | ElementType.METHOD)的注解才可能出现在返回类型的上下文中:
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
}如果注解只声明了 ElementType.METHOD,即使写在返回类型位置(如 @NotNull String),也不会被 getAnnotatedReturnType() 捕获。
使用 getAnnotatedReturnType() + getAnnotationsByType()
Method.getAnnotatedReturnType() 返回的是 AnnotatedType 实例,它代表“带注解的类型”,不是方法本身。要获取 TYPE_USE 注解,不能调用 .getAnnotations()(那是针对声明式注解的),而应:
- 调用
annotatedType.getAnnotationsByType(NotNull.class)—— 支持继承(如元注解含@Inherited) - 或调用
annotatedType.getDeclaredAnnotationsByType(NotNull.class)—— 仅查直接声明的注解,更常用、更准确
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
Method method = SomeClass.class.getMethod("getString");
AnnotatedType returnType = method.getAnnotatedReturnType();
NotNull[] annotations = returnType.getDeclaredAnnotationsByType(NotNull.class);
// 若方法声明为:@NotNull String getString() → annotations 长度为 1注意泛型与嵌套类型的注解位置
TYPE_USE 注解可出现在复杂类型任意位置,例如:
@NotNull List getData() { ... }
// 此时:
// - @NotNull 作用于整个返回类型 List<...> → 可通过 getAnnotatedReturnType() 获取
// - @NonNull 作用于泛型参数 String → 需从 AnnotatedParameterizedType 中进一步提取
</...>若需获取泛型内部的 TYPE_USE 注解(如 @NonNull String),需向下转型:
- 判断
returnType是否为AnnotatedParameterizedType - 调用
getAnnotatedActualTypeArguments()获取每个泛型参数的AnnotatedType - 再对每个参数调用
getDeclaredAnnotationsByType(...)
常见误区
以下做法无法获取 TYPE_USE 注解:
-
method.getAnnotation(NotNull.class)—— 查的是方法声明上的注解,不是返回类型的 -
method.getReturnType().getAnnotations()——Class上只有DECLARATION级注解,不包含TYPE_USE -
returnType.getAnnotations()—— 返回空数组,因为AnnotatedType.getAnnotations()不处理TYPE_USE(JDK 设计如此)
务必使用 getDeclaredAnnotationsByType(T.class) 或 getAnnotationsByType(T.class)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










