java - 使用 Java doc API 从 DeclaredType/TypeMirror 获取合格类型
问题描述
我有DeclaredType
一个字段,我想获得该字段的完全限定类型(原始类型?)。例如,如果该字段是:
public static Optional<String> foo;
我想得到java.util.Optional
。
目前我可以通过以下方式获取包名:
env.getElementUtils().getPackageOf(declaredType.asElement());
我可以获得该类型的类型参数,但是我回到了同样的问题,我最终遇到了一个List
我TypeMirror
不知道如何获取类型的限定名称的问题。
我注意到我可以打电话TypeMirror#toString()
,这将返回(对于上述)类似:
java.util.Optional<java.lang.String>
我想我可以切掉前面的所有东西,<
但这感觉就像一个黑客。
作为参考,这是我获得该领域的方式:
private VariableElement getFieldWithName(DocletEnvironment environment, TypeElement classDoc, String fieldName) {
for(VariableElement e : ElementFilter.fieldsIn(environment.getElementUtils().getAllMembers(classDoc))) {
if(e.getSimpleName().toString().equals(fieldName)) {
return e;
}
}
return null;
}
TypeElement classElement = env.getElementUtils().getTypeElement(MyClass.class.getCanonicalName());
VariableElement fieldDoc = getFieldWithName(env, classElement, "foo");
DeclaredType declaredType = (DeclaredType) fieldDoc.asType();
解决方案
我测试了这段代码,它适用于 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实现:
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
推荐阅读
- anylogic - 绘制多级公路运输网络时出现奇怪的图形故障
- mysql - SQL 非负数和 TinyInt 的问题
- redmine-plugins - 在 redmine 上安装清单插件后出现 500 内部服务器错误
- reactjs - 减速器没有更新
- ssh - 如何使用用户名/主机名和密码 ssh 到远程 ubuntu 笔记本电脑?
- jenkins - 如何将在从节点上自动生成的 .jenkins 更改为另一个路径
- php - 提交 PHP_SELF 表单后,如何重定向到新页面?
- java - 在新线程上启动另一个 android 应用程序
- python - 为什么轴 ax.spines 没有显示轴?
- nuget-package - Nuget 包管理器的包源在源中不可用