Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javax.lang.model: How do I get the type of a field?

In java.lang.reflect, one would do:

Field someField = ...;
Class<?> fieldType = someField.getType();

But what do I do with javax.lang.model's VariableElement (which may or may not represent a field)? A corresponding return value would be (I guess) TypeElement.

VariableElement someField = ...;
TypeElement fieldType = someField.???;

So, in javax.lang.model, how do I get the type (or TypeElement) of a field, represented by VariableElement?

BTW, there is not a single Stackoverflow-tag which would fit to javax.lang.model ;)

like image 920
java.is.for.desktop Avatar asked Dec 19 '10 12:12

java.is.for.desktop


2 Answers

Well, I don't know, it that's the right way to do this.
Would be nice if someone, who actually understands this API, told me.

But well, seams to work.

public class SomeClass {
  private final ProcessingEnvironment pe = /* get it somewhere */;
  private final Types typeUtils = pe.getTypeUtils();

  public TypeElement getExtracted(VariableElement ve) {
    TypeMirror typeMirror = ve.asType();
    Element element = typeUtils.asElement(typeMirror);

    // instanceof implies null-ckeck
    return (element instanceof TypeElement)
        ? (TypeElement)element : null;
  }
}

It seems that the class Types has to be got from current ProcessingEnvironment because some of its internals depend on it, so it's not a usual utility class.

like image 156
java.is.for.desktop Avatar answered Nov 10 '22 12:11

java.is.for.desktop


I stumbled across this trying to make sense out of the new JDK Doclet hairball. The accepted answer didn't work for me because, well, Doclet has various internal classes that cannot be used. Furthermore, this answer is more akin to "how do I convert TypeMirror to TypeElement"; given the paucity of java.lang.model SO questions+answers, I thought I'd post this anyway.

Here's what I did:

import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

@Override
public boolean run(DocletEnvironment docEnv) {
    ...        
    elementUtils = docEnv.getElementUtils();
    typeUtils    = docEnv.getTypeUtils();
    ...
}

When you have a TypeElement t that is a class/interface "kind" you can do something like this to go from TypeMirror to TypeElement.

TypeMirror   p = t.getSuperclass();
TypeElement pe = (TypeElement) typeUtils.asElement(p);

I hope this helps someone.

like image 2
Tim Beres Avatar answered Nov 10 '22 14:11

Tim Beres