#java
Вопрос:
У меня есть процессор аннотаций. Я получаю список переменных класса, который был аннотирован моей аннотацией таким образом:
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
for (Element el : annotatedElements) {
try {
generate(el);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
private void generate(Element annotatedElement) throws IOException {
TypeElement targetClass = (TypeElement) annotatedElement;
List<? extends Element> enclosedElements = targetClass.getEnclosedElements();
List<VariableElement> fields = new ArrayList<>(enclosedElements.size());
for (Element field : enclosedElements) {
if (field.getKind() == ElementKind.FIELD amp;amp; !field.getModifiers().contains(Modifier.STATIC)) {
fields.add((VariableElement) field);
}
}
processFields(fields);
}
Теперь fields
список содержит список всех переменных. Но мне нужно извлечь ТИП переменных, поэтому, например, если класс имеет
private String blabla
я хочу получить String
Я делаю это следующим образом:
void processFields(List<VariableElement> elements){
List<String> types =elements
.stream()
.map( e -> e.asType().toString())
.collect(Collectors.toList());
}
Список types
теперь содержит все типы переменных. Однако, если у меня будет такой класс, как этот
@MyAnnotation
public class Test{
@NotBlank(message = "message")
private String name;
}
Тип переменной name
не является строковым, ее
(@javax.validation.constraints.NotBlank(message="message") :: java.lang.String
Как я могу тогда просто печатать без аннотаций? Есть ли какой-нибудь способ?
Спасибо за помощь!
Ответ №1:
Добавьте элементы и переопределите init()
, чтобы получить экземпляры элементов и типов.
...
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
...
/** See {@link javax.annotation.processing.ProcessingEnvironment#getElementUtils()}. */
protected Elements elements = null;
/** See {@link javax.annotation.processing.ProcessingEnvironment#getTypeUtils()}. */
protected Types types = null;
...
@Override
public void init(ProcessingEnvironment processingEnv) {
elements = processingEnv.getElementUtils();
types = processingEnv.getTypeUtils();
}
...
К вашему сведению, вы можете упростить свой generate(Element)
метод:
...
import javax.lang.model.util.ElementFilter;
...
private void generate(Element annotatedElement) throws IOException {
List<VariableElement> fields =
ElementFilter.fieldsIn(Collections.singleton(annotatedElement)).stream()
.filter(t -> (! t.getModifiers().contains(Modifier.STATIC)))
.collect(Collectors.toList());
processFields(fields);
}
Ваш processFields(List<VariableElement>)
метод может выглядеть примерно
так, как показано ниже. Я сделал все шаги явными, но вы можете посмотреть на
элемент типа
и
имя
методы для определения нужной строки.
void processFields(List<VariableElement> in) {
List<String> out =
in.stream()
.map(e -> e.asType()) /* javax.lang.model.type.TypeMirror */
.map(e -> types.asElement(e)) /* javax.lang.model.element.Element */
.map(e -> (TypeElement) e) /* javax.lang.model.element.TypeElement */
.map(e -> e.getQualifiedName()) /* javax.lang.model.element.Name */
.map(e -> e.toString())
.collect(Collectors.toList());
}