关于javaparser:如何获取java类的全限定名 您所在的位置:网站首页 类的完全限定名 关于javaparser:如何获取java类的全限定名

关于javaparser:如何获取java类的全限定名

2023-08-08 09:46| 来源: 网络整理| 查看: 265

我有一个像下面这样的课程。

1234public class Login {     private Keyword browser;     private String page; }

Keyword是不同程序包中的类。 我想在使用javaparser解析Login类时获得类Keyword的完全限定名称。

相关讨论 正如@EJP在他的回答中所暗示的那样,除了解析源代码之外,您还必须至少执行最少的代码分析量。 例如。 像这样:(1)查看类型引用是否已经是限定名称;(2)如果看不到导入,(3)否则将类型名称附加到包声明中。 另请注意,JavaParser移至GitHub github.com/javaparser/javaparser

您不能使用JavaParser来执行此操作,因为JavaParser不能解析符号。要将名称关键字解析为一个类,您需要做几件事: *实现适当的范围规则(您需要查找内部类,然后在同一文件中查找其他类,然后考虑导入...) *它取决于用于编译的类路径:将其更改为同一类可能会以不同方式解析

为此,应编写一个符号解析器:它不是简单的,但是可行的。如果您对此主题感兴趣,可以阅读我刚刚在Clojure中写的《如何为Java构建符号求解器》一文。该帖子还包含该代码的链接,可在GitHub上免费获得。

资料来源:我是JavaParser的撰稿人

您可以使用JavaParser Symbol Solver:

12345     com.github.javaparser     javaparser-symbol-solver-core     3.14.5

然后使用以下配置解析代码:

12345678910CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(),                                                      new JavaParserTypeSolver(sourceRoot)); final ParserConfiguration config = new ParserConfiguration()                 .setStoreTokens(true)                 .setSymbolResolver(new JavaSymbolSolver(combinedTypeSolver)); SourceRoot root = new SourceRoot(Paths.get("/path/to/project/")); root.parse("", config, (Path localPath, Path absolutePath, ParseResult result) -> {                 // Do something with the CompilationUnit                 return Result.DONT_SAVE;             });

现在,我们可以使用以下方法获取任何ReferenceType的完全限定标识符:

12ResolvedType type = referenceType.resolve(); String qualifiedName = type.getQualifiedName();

相关讨论 太好了-这也对我有用。 但是,我仍然需要其他答案中的getClass(Node n1)方法。 没有等效的API吗? @Fuhrmanator我不认为有一个等效于该方法号的API。

我编写了一种方法,该方法可以基于ClassOrInterfaceDeclaration对象(JavaParser的最新版本)获取完全限定名称:

12345678910111213141516171819202122232425262728293031    private static String getFullyQualifiedName(ClassOrInterfaceDeclaration c2) {         String name ="";         ClassOrInterfaceDeclaration parentClass = c2.getParentNode().isPresent() ? getClass(c2.getParentNode().get()): null;         if(parentClass!=null) {             name+=getFullyQualifiedName(parentClass)+".";         } else {             CompilationUnit u = getCompilationUnit(c2);             if(u!=null && u.getPackageDeclaration().isPresent()) {                 name+=u.getPackageDeclaration().get().getNameAsString()+".";             }         }         return name+c2.getNameAsString();     }     private static ClassOrInterfaceDeclaration getClass(Node n1) {         while (!(n1 instanceof ClassOrInterfaceDeclaration)) {             if(n1.getParentNode().isPresent()) {                 n1 = n1.getParentNode().get();             } else return null;         }         return (ClassOrInterfaceDeclaration)n1;     }     private static CompilationUnit getCompilationUnit(Node n1) {         while (!(n1 instanceof CompilationUnit)) {             if(n1.getParentNode().isPresent()) {                 n1 = n1.getParentNode().get();             } else return null;         }         return (CompilationUnit)n1;     }

如果获得该类的ClassOrInterfaceType,则可以使用更简单的版本:

123456    private static String getFullyQualifiedName(ClassOrInterfaceType e) {         String name ="";         if(e.getScope().isPresent())             name+=getFullyQualifiedName(e.getScope().get())+".";         return name+e.getNameAsString();     }

我希望这对任何人都有帮助!

相关讨论 对我有用。 您是否找到了使用最新API的更简洁的方法? @Fuhrmanator是的,我做到了! 请查看以下答案:stackoverflow.com/a/57002990/5320300

到目前为止,似乎没有人看过这个问题,但是如果您要解析源代码,则源代码位于当前包中,或者由import语句导入。

我本来希望Java解析器编写者或用户知道这一点。

相关讨论 如果所讨论的类型来自通配符import语句,则很难解析限定名称。

JavaParser不会解析导入(无论如何通常不认为这是其工作)。您必须手动完成导入语句并搜索Keyword是否属于它们。请记住,Java隐式地执行import java.lang.*,否则您将无法解析诸如String之类的类型。

Spring Roo有一个JavaParserUtils类,其中包含方法getJavaType(CompilationUnitServices compilationUnitServices, ClassOrInterfaceDeclaration cid)。该类不是为在Roo之外使用而设计的,但是您可以将其用作解决问题的模板。

如果您使用的是访问者,似乎您只能获得源文件中具有类型名称的开始和结束索引。那不会让您获得完全合格的名称。

因此,您还应该在自定义访问者中实现visit(ImportDeclaration, A)方法。然后,此方法必须存储导入声明,以便稍后(在调用方法visit(FieldDeclaration, A)时)可以引用导入的包并组装完全限定的名称。

使用Java反射(java.lang.reflect)

这可能是解决您问题的更好方法,

使用实例。

在Java中使用"实例"



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有