使用 Java 6 注释处理器获取泛型类型的限定类名
2022-09-03 14:50:51
我正在使用JDK 6的注释处理API开发一个小代码生成器,并且试图在类中获取字段的实际泛型类型。为了更清楚,假设我有一个这样的类:
@MyAnnotation
public class User {
private String id;
private String username;
private String password;
private Set<Role> roles = new HashSet<Role>();
private UserProfile profile;
}
这是我的注释处理器类:
@SupportedAnnotationTypes({ "xxx.MyAnnotation" })
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class MongoDocumentAnnotationProcessor extends AbstractProcessor {
private Types typeUtils = null;
private Elements elementUtils = null;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
typeUtils = processingEnv.getTypeUtils();
elementUtils = processingEnv.getElementUtils();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
debug("Running " + getClass().getSimpleName());
if (roundEnv.processingOver() || annotations.size() == 0) {
return false;
}
for (Element element : roundEnv.getRootElements()) {
if (element.getKind() == ElementKind.CLASS && isAnnotatedWithMongoDocument(element)) {
for (VariableElement variableElement : ElementFilter.fieldsIn(element.getEnclosedElements())) {
String fieldName = variableElement.getSimpleName().toString();
Element innerElement = typeUtils.asElement(variableElement.asType());
String fieldClass = "";
if (innerElement == null) { // Primitive type
PrimitiveType primitiveType = (PrimitiveType) variableElement.asType();
fieldClass = typeUtils.boxedClass(primitiveType).getQualifiedName().toString();
} else {
if (innerElement instanceof TypeElement) {
TypeElement typeElement = (TypeElement) innerElement;
fieldClass = typeElement.getQualifiedName().toString();
TypeElement collectionType = elementUtils.getTypeElement("java.util.Collection");
if (typeUtils.isAssignable(typeElement.asType(), collectionType.asType())) {
TypeVariable typeMirror = (TypeVariable)((DeclaredType)typeElement.asType()).getTypeArguments().get(0);
TypeParameterElement typeParameterElement = (TypeParameterElement) typeUtils.asElement(typeMirror);
// I am stuck here. I don't know how to get the
// full qualified class name of the generic type of
// property 'roles' when the code processes the User
// class as above. What I want to retrieve is the
// 'my.package.Role' value
}
}
}
}
}
}
return false;
}
private boolean isAnnotated(Element element) {
List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
if (annotationMirrors == null || annotationMirrors.size() == 0) return false;
for (AnnotationMirror annotationMirror : annotationMirrors) {
String qualifiedName = ((TypeElement)annotationMirror.getAnnotationType().asElement()).getQualifiedName().toString();
if ("xxx.MyAnnotation".equals(qualifiedName)) return true;
}
return false;
}
}
任何提示将不胜感激!