gpt4 book ai didi

Java AnnotationProcessing - 获取注释的字段

转载 作者:行者123 更新时间:2023-12-02 12:18:39 25 4
gpt4 key购买 nike

我有一个关于 API AnnotationProcessing 的问题。这是一个小例子。

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface MyAnnotation
{
String strNumberOne() default "";

String strNumberTwo() default "";

String strNumberThree() default "";
}


public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
// I do not know how to beginn here
return true;
}
}

public class MyClass
{
@MyAnnotation(strNumberOne="one", strNumberTwo= "two")
private String strARandomString;
}

现在我想读取注释中声明的字段,如果有未声明的字段,我的程序应该采用默认值。

我想将值写入列表中。最后我的列表应该是这样的:

LinkedList<String> s = new LinkedList<>();
s.add(strNumberOne); // "one"
s.add(strNumberTwo); // "two"
s.add(strNumberThree); // (default) ""

我该怎么做?我找到了一个可以提供帮助的方法。在接口(interface)“Elements”中,方法名称为“getElementValuesWithDefaults()”。但我不知道怎么用..我还想知道 TypeElement 和 Element 之间有什么区别。我很感谢每一个答案! :)

最诚挚的问候!

最佳答案

如果 MyAnnotation 是您的处理器支持的注释,那么您只需编写如下内容:

@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment env) {
if (shouldClaim(annotations)) {
for (Element e : env.getElementsAnnotatedWith(MyAnnotation.class)) {
MyAnnotation a = e.getAnnotation(MyAnnotation.class);

String str1 = a.strNumberOne();
String str2 = a.strNumberTwo();
String str3 = a.strNumberThree();
// Add them to a List or whatever you need.
}

return true;
}
return false;
}

private boolean shouldClaim(Set<? extends TypeElement> annotations) {
Set<String> supported = getSupportedAnnotationTypes();
for (TypeElement a : annotations) {
if (supported.contains(a.getQualifiedName().toString()))
return true;
}
return false;
}

shouldClaim 方法的逻辑由process 的文档进行了解释。 。如果您的注释支持例如,则会更加复杂*name.* 形式的类型,但通常不会。 (有关这些含义的说明,请参阅 getSupportedAnnotationTypes。)

如果 MyAnnotation 不是您的处理器支持的注释,那么您需要通过 getElementValuesWithDefaults 如果它是您正在编译的包中声明的类型。由于注释处理发生在编译期间,因此正在编译的源文件的类文件还不存在,这就是我们使用 Element API 的原因。

Element 表示某种类型的声明,例如类、方法或变量。 TypeElement 表示类、接口(interface)、枚举或注释类型声明。 TypeElement 就我们可以用它做的事情而言与 Class 类似,除了我们可以将 TypeElement 用于不一定是类的类。已编译。

要通过元素 API 获取注释值,您需要执行以下操作:

Elements    elements     = processingEnv.getElementUtils();
TypeElement myAnnotation = elements.getTypeElement("com.example.MyAnnotation");

for (Element e : env.getElementsAnnotatedWith(myAnnotation)) {
for (AnnotationMirror mirror : e.getAnnotationMirrors()) {
DeclaredType annotationType = mirror.getAnnotationType();
Element annotationDecl = annotationType.asElement();

if (myAnnotation.equals(annotationDecl)) {
Map<? extends ExecutableElement, ? extends AnnotationValue> values =
elements.getAnnotationValuesWithDefaults(mirror);

String str1 = (String) getValue(values, "strNumberOne");
String str2 = (String) getValue(values, "strNumberTwo");
String str3 = (String) getValue(values, "strNumberThree");
// ...
}
}
}

private Object getValue(Map<? extends ExecutableElement,
? extends AnnotationValue> values,
String name) {
for (Map.Entry<? extends ExecutableElement,
? extends AnnotationValue> e : values.entrySet()) {
if (name.contentEquals(e.getKey().getSimpleName()))
return e.getValue().getValue();
}
return null;
}

这很痛苦,但我们只需要使用元素 API 如果我们感兴趣的注释是正在编译的类之一。

我们可能还想找到 AnnotationMirror 和/或 AnnotationValue,以使用 Messager.printMessage 之一在特定元素上引发某种类型的消息。重载将上述对象之一作为参数。

关于Java AnnotationProcessing - 获取注释的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45965555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com