使用Java doc API从DeclaredType / TypeMirror获取合格的类型

时间:2018-12-31 00:46:37

标签: java javadoc java-11

我有一个字段DeclaredType,我想获取该字段的完全限定类型(原始类型吗?)。例如,如果字段为:

public static Optional<String> foo;

我想得到java.util.Optional

目前,我可以通过以下方式获取软件包名称:

env.getElementUtils().getPackageOf(declaredType.asElement());

我可以得到该类型的类型参数,但是回到同样的问题,最终得到List的{​​{1}},但我不知道如何获取该类型的限定名称。类型。

我注意到我可以打电话给TypeMirror,这将返回(上述)类似的内容:

TypeMirror#toString()

我想我可以切掉java.util.Optional<java.lang.String> 前面的所有内容,但这听起来像是一个黑客。

作为参考,这是我获得该领域的方式:

<

2 个答案:

答案 0 :(得分:0)

我测试了此代码,它可在Apache Netbeans 10和Jdk11上运行。 使用((DeclaredType) variableElement.asType()).asElement().toString()

            DeclaredType declaredType = (DeclaredType) e.asType();//e is VariableElement from the loop
            fullyQualifiedName = declaredType.asElement().toString();

测试类:

class MyClass1 {
public static Optional<String> foo;
public static List<String> newList;
public static MyClass2 obj;
public Media media;
public void calculate(Double dl) {
}}

class MyClass2 extends MyClass1{
public static Color cl;
}

还有Doclet implementation

public class TestVarElement implements Doclet {

 public void testFields(DocletEnvironment env) {
    TypeElement typeElement = env.getElementUtils().getTypeElement(MyClass1.class.getCanonicalName());
    System.out.println("Test for 'foo': "+getFieldWithName(env,typeElement,"foo"));
    System.out.println("Test for 'newList': "+getFieldWithName(env,typeElement,"newList"));
    System.out.println("Test for 'obj': "+getFieldWithName(env,typeElement,"obj"));
    System.out.println("Test for 'media': "+getFieldWithName(env,typeElement,"media"));
}

    private String getFieldWithName(DocletEnvironment env, TypeElement classDoc, String fieldName) {
        String fullyQualifiedName = "";
        for (VariableElement e : ElementFilter.fieldsIn(env.getElementUtils().getAllMembers(classDoc))) {
            if (e.getSimpleName().toString().equals(fieldName)) {
                DeclaredType declaredType = (DeclaredType) e.asType(); //The type of the VariableElement
                fullyQualifiedName = declaredType.asElement().toString(); //Get the fqn 
                break;
            }
        }
        return fullyQualifiedName;
    }
   @Override
    public boolean run(DocletEnvironment docEnv) {
        testFields(docEnv);
        return true;
    }

    ... Other Overrids

    }

调试/运行程序:

     public class NewClass {
            public static void main(String[] args) {
                ToolProvider javadoc=ToolProvider.findFirst("javadoc").orElseThrow();
                int result=javadoc.run(System.out, System.err, new String[]{"-doclet",TestVarElement.class.getName(),"C:\\Users\\Super3\\Documents\\NetBeansProjects\\Myproject\\src\\pk\\TestVarElement.java"});

//The following is for java 8 or older, the implementation is diferent where `start` method is used instead of `run`.
     //Main.execute (new String[]{"-doclet",TestVarElement.class.getName(),"C:\\Users\\Super3\\Documents\\NetBeansProjects\\Myproject\\src\\pk\\TestVarElement.java"});
          }
        }

输出

  

测试'foo':java.util.Optional

     

测试“ newList”:java.util.List

     

测试“ obj”:pk.MyClass2

     

测试“媒体”:javax.print.attribute.standard.Media

答案 1 :(得分:0)

要将通用类型转换为原始类型,请在不使用任何类型参数的情况下进行解析。请参见Types#getDeclaredType,而无需指定任何类型即可调用:

  

如果为零,并且类型元素为通用元素,则返回类型元素的原始类型

DeclaredType rawType = env.getTypeUtils().getDeclaredType(typeElement);