如何解决如何访问方法参数的通用类型参数上的注释?
假设我想使用反射检查以下类:
class Foo {
void bar(List<@Important String> b) {}
}
请注意,@Important
注释在参数本身上不是 (然后我可以使用Method.getParameterAnnotations()
),但是在其类型参数上(注释为声明具有ElementType.TYPE_USE
)。
有没有办法在Java 11中读取此类注释?
解决方法
不幸的是,Reflection API的这一部分太可怕了。基本类型没有必要的查询方法,也没有Visitor API等。因此,任何试图进行全面自省的代码都别无选择,只能执行许多instanceof
检查,以处理所有可能的情况。
如果您事先知道该方法的类型应该是参数化类型,并且只想检查其第一个类型参数的注释,则可以做得更简单一些,而忽略所有其他可能的情况:
import java.lang.annotation.*;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.Method;
import java.util.*;
public class Main {
public static void main(String[] args) throws NoSuchMethodException {
Method m = Foo.class.getDeclaredMethod("bar",List.class);
var at = m.getAnnotatedParameterTypes()[0];
var ata = ((AnnotatedParameterizedType)at).getAnnotatedActualTypeArguments()[0];
// get all annotations
for(var a: ata.getAnnotations()) {
System.out.println(a);
}
// or check the presence of a known annotation
System.out.println(ata.getAnnotation(Important.class) != null);
}
class Foo {
void bar(List<@Important String> b) {}
}
}
@Important()
true
,
TL; DR —在类型参数,类型变量和类型参数之间查看此答案discussing the subtle differences。
冗长的版本
„ …请注意,
@Important
批注…在其 type参数上 ... “
在您的 Foo
声明中……
class Foo {
void bar(List<@Important String> b) {}
}
… String
不是type parameter。它也不是type variable。在您的代码段中, String
是type argument。
尽管我在saying originally上得到纠正,ReferenceType
类型的参数不能有注释(turns out they can),但我将把这些JLS产生的内容保留在这里,让我保持谦虚的态度 ...
4.5.1. Type Arguments of Parameterized Types
类型参数可以是引用类型或通配符。通配符很有用 在只需要部分了解类型参数的情况下。
TypeArguments:
< TypeArgumentList >
TypeArgumentList:
TypeArgument
{,TypeArgument}
TypeArgument:
ReferenceType
Wildcard
Wildcard:
{Annotation}
?
[WildcardBounds]
WildcardBounds:
extends
ReferenceType
super
ReferenceType
出于完整性考虑, 类型参数 ...
的JLS生成4.4. Type Variables
类型变量是在类,接口,方法和构造函数主体中用作类型的不合格标识符。
类型变量是通过泛型类,接口,方法或构造函数的类型参数的声明引入的。
TypeParameter:
{TypeParameterModifier} TypeIdentifier [TypeBound]:
TypeParameterModifier:
Annotation
…
尽管我从未在野外见过人-直到今天-之前的JLS作品证实了带注释的 String
在您的代码段中输入参数 确实是合法的Java。每天学习新东西!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。