【号外】-一款高效的Java源代码解析器

简介: 【号外】-一款高效的Java源代码解析器QDox

微信截图_20220612174009.png

QDox

QDox 一款简单,高效的Java源代码解析器,可以提取Java类、接口、方法、参数名称、类型等。

另外不得不说的是这个项目可以说是一个上古时期的项目了,看了 Github 上的提交记录,最早的一条提交记录是 2002 年的时候,因为这个项目之前使用的是 svn,所以具体时间可能更早。一个开源项目维护了快 20 年也是一件挺令人钦佩的事。不过到目前为止,这个项目在 github 上只有 303个 star,如果这个项目对你有所帮助,希望大家可以给作者一个 star。github 上有太多类似的项目默默无闻的出现,又默默无闻的消逝。

不过据说maven 的官方 javadoc 插件 maven-javadoc-plugin 就是使用它来解析代码中的 doc tags 的。所以可能你没有直接使用它,但是它其中已经在你本地的 maven 仓库内躺着了。有官方背书,对于它的使用就比较放心了。

github:https://github.com/paul-hammant/qdox

简单介绍一下怎么用。

集成

目前最新版本2.0-M10

Maven

<dependency>
    <groupId>com.thoughtworks.qdox</groupId>
    <artifactId>qdox</artifactId>
    <version>2.0-M10</version>
</dependency>

Gradle

compile group: 'com.thoughtworks.qdox', name: 'qdox', version: '2.0-M10'

用法

package com.mini.test;
import java.util.Random;
/**
 * QDox 测试
 * @author: jujun chen
 * @date: 2019/07/07
 */
public class TestClass extends BaseTestClass implements Test{
    /**
     * 登录接口
     * @param userName 用户名
     * @param password 密码
     * @return Person对象
     */
    public Person Login(String userName, String password) {
        int age = new Random().nextInt();
        Person person = new Person(userName, password, age);
        System.out.println(person);
        return person;
    }
}
class Person {
    private String userName;
    private String password;
    private int age;
    public Person(String userName, String password, int age) {
        this.userName = userName;
        this.password = password;
        this.age = age;
    }
}
class BaseTestClass {
}
interface Test {
}

测试:

@Test
    public void getMeClass() throws IOException {
        JavaProjectBuilder builder =  new  JavaProjectBuilder();
        builder.addSourceTree(new File("src/main/java/com/mini/test"));
        //目录下的所有class
        System.out.println("====目录下的所有class====");
        Collection<JavaClass> classes = builder.getClasses();
        System.out.println(classes + "\n");
        //根据class全限定名获取
        JavaClass javaClass = builder.getClassByName("com.mini.test.TestClass");
        //获取类的注释
        System.out.println("====获取类的注释====");
        System.out.println(javaClass.getComment());
        List<DocletTag> classTags = javaClass.getTags();
        classTags.forEach(item -> {
            System.out.println(item.getName() + "" + item.getValue());
        });
        System.out.println("\n");
        //获取继承的父类
        System.out.println("====获取继承的父类====");
        System.out.println(javaClass.getSuperClass() + "\n");
        //获取接口
        System.out.println("====获取接口====");
        System.out.println(javaClass.getImplements() + "\n");
        //获取方法
        System.out.println("====获取方法====");
        List<JavaMethod> methods = javaClass.getMethods();
        System.out.println(methods + "\n");
        //get Login方法
        JavaMethod javaMethod = methods.get(0);
        //方法返回类型
        System.out.println("====获取方法返回类型====");
        System.out.println(javaMethod.getReturns() + "\n");
        //获取参数
        System.out.println("====获取参数====");
        List<JavaParameter> parameters = javaMethod.getParameters();
        System.out.println(parameters);
        //获取参数类型
        //get userName参数
        JavaParameter parameter = parameters.get(0);
        //参数名称
        System.out.println(parameter.getName());
        //参数类型
        System.out.println(parameter.getType() + "\n");
        System.out.println("====获取方法注释====");
        //获取方法注释
        System.out.println(javaMethod.getComment());
        //获取参数备注
        List<DocletTag> tags  =javaMethod.getTags();
        tags.forEach(item -> {
            System.out.println(item.getName() + ":" + item.getValue());
        });
    }

测试结果:

====目录下的所有class====
[class com.mini.test.TestClass, class com.mini.test.Person, class com.mini.test.BaseTestClass, interface com.mini.test.Test]
====获取类的注释====
QDox 测试
author:jujun chen
date:2019/07/07
====获取继承的父类====
com.mini.test.BaseTestClass
====获取接口====
[com.mini.test.Test]
====获取方法====
[public com.mini.test.Person com.mini.test.TestClass.Login(java.lang.String,java.lang.String)]
====获取方法返回类型====
com.mini.test.Person
====获取参数====
[String userName, String password]
userName
java.lang.String
====获取方法注释====
登录接口
param:userName 用户名
param:password 密码
return:Person对象

总结

使用该工具,可以解析Java源代码,很方便,速度也很快😎。脑洞一下吧,可以利用它来做点什么,提高生产力。

相关文章
|
28天前
|
存储 缓存 安全
Java内存模型深度解析:从理论到实践####
【10月更文挑战第21天】 本文深入探讨了Java内存模型(JMM)的核心概念与底层机制,通过剖析其设计原理、内存可见性问题及其解决方案,结合具体代码示例,帮助读者构建对JMM的全面理解。不同于传统的摘要概述,我们将直接以故事化手法引入,让读者在轻松的情境中领略JMM的精髓。 ####
34 6
|
1天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
23天前
|
Java 编译器
Java 泛型详细解析
本文将带你详细解析 Java 泛型,了解泛型的原理、常见的使用方法以及泛型的局限性,让你对泛型有更深入的了解。
36 2
Java 泛型详细解析
|
24天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
51 12
|
24天前
|
测试技术 开发者 Python
使用Python解析和分析源代码
本文介绍了如何使用Python的`ast`模块解析和分析Python源代码,包括安装准备、解析源代码、分析抽象语法树(AST)等步骤,展示了通过自定义`NodeVisitor`类遍历AST并提取信息的方法,为代码质量提升和自动化工具开发提供基础。
40 8
|
21天前
|
存储 算法 Java
Java内存管理深度解析####
本文深入探讨了Java虚拟机(JVM)中的内存分配与垃圾回收机制,揭示了其高效管理内存的奥秘。文章首先概述了JVM内存模型,随后详细阐述了堆、栈、方法区等关键区域的作用及管理策略。在垃圾回收部分,重点介绍了标记-清除、复制算法、标记-整理等多种回收算法的工作原理及其适用场景,并通过实际案例分析了不同GC策略对应用性能的影响。对于开发者而言,理解这些原理有助于编写出更加高效、稳定的Java应用程序。 ####
|
21天前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
23天前
|
Java 数据库连接 开发者
Java中的异常处理机制:深入解析与最佳实践####
本文旨在为Java开发者提供一份关于异常处理机制的全面指南,从基础概念到高级技巧,涵盖try-catch结构、自定义异常、异常链分析以及最佳实践策略。不同于传统的摘要概述,本文将以一个实际项目案例为线索,逐步揭示如何高效地管理运行时错误,提升代码的健壮性和可维护性。通过对比常见误区与优化方案,读者将获得编写更加健壮Java应用程序的实用知识。 --- ####
|
27天前
|
数据采集 存储 Web App开发
Java爬虫:深入解析商品详情的利器
在数字化时代,信息处理能力成为企业竞争的关键。本文探讨如何利用Java编写高效、准确的商品详情爬虫,涵盖爬虫技术概述、Java爬虫优势、开发步骤、法律法规遵守及数据处理分析等内容,助力电商领域市场趋势把握与决策支持。
|
27天前
|
安全 Java
Java中WAIT和NOTIFY方法调用时机的深层解析
在Java多线程编程中,`wait()`和`notify()`方法的正确使用对于线程间的协调至关重要。这两个方法必须在同步块或同步方法中调用,这一规定的深层原因是什么呢?本文将深入探讨这一机制。
36 5

推荐镜像

更多