JDK tools,2020-2021字节跳动Java面试真题解析

通过文档我们可以发现,其实我们只用自定义一个 Doclet 类就行了,至于怎么定义其实文档中已经写的很详细了,还给出了具体代码片段,我们可以直接搬过来进行验证即可,代码如下:


public class CustomerDoclet extends Doclet {

  public static boolean start(RootDoc root) {

    ClassDoc[] classes = root.classes();

    //注释文档信息,自己爱怎么解析组织就怎么解析了,看自己需求

    return true;

  }

}



public static void main(String[] args) {

     String[] docArgs =

         new String[] {

           "-doclet", CustomerDoclet.class.getName(), "/home/yan/test/cn/test/JavaSource.java"

         };

     com.sun.tools.javadoc.Main.execute(docArgs);

  } 

简单吧,运行上面代码段就能自定义 javadoc 输出解析了。跑了下发现没问题,那就开始搞事情吧。

[](

)实现一个 gradle 插件进行 javadoc 自定义操作


这里我们为了简单和直接说明核心,所以打算实现一个检查 android、androidLibrary、java、javaLibrary 代码源文件中是否包含 javadoc @author 的插件,插件名称 gradle-javadoc-checker,具体完整插件源码可以访问[https://github.com/yanbober/gradle-javadoc-checker](

)获取。

注意:这部分内容需要你先对 gradle 插件开发比较熟悉才能看懂,所以建议先掌握所说的知识后进行研读。

[](

)添加依赖


dependencies {

    compile gradleApi()

    compile 'com.android.tools.build:gradle:3.1.0'

    //tools.jar 的依赖

    compile files(org.gradle.internal.jvm.Jvm.current().toolsJar)

} 

[](

)编写自定义 javadoc 判断 @author 工具


public class JavaDocReader {

    private static RootDoc root;

	//自定义 doclet

    public static class CustomerDoclet {

        public static boolean start(RootDoc root) {

            JavaDocReader.root = root;

            return true;

        }

    }



    //tools.jar 中 javadoc 的封装

    public static RootDoc process(String[] extraArges) {

        List<String> argsOrderList = new ArrayList<>();

        argsOrderList.add("-doclet");

        argsOrderList.add(CustomerDoclet.class.getName());

        argsOrderList.addAll(Arrays.asList(extraArges));

        String[] args = argsOrderList.toArray(new String[argsOrderList.size()]);

        System.out.println(args);

        Main.execute(args);

        return root;

    }



    //tools.jar 中 javadoc 的封装

    public static void process(List<String> sourcePaths, List<String> javapackages,

                               List<String> excludePackages, String outputDir) throws Exception {

        String paths = list2formatString(sourcePaths, ";");

        String includes = list2formatString(javapackages, ":");

        String excludes = list2formatString(excludePackages, ":");



        List<String> argsOrderList = new ArrayList<>();

        argsOrderList.add("-doclet");

        argsOrderList.add(CustomerDoclet.class.getName());



        if (paths != null && paths.length() > 0) {

            argsOrderList.add("-sourcepath");

            argsOrderList.add(paths);

        }



        argsOrderList.add("-encoding");

        argsOrderList.add("utf-8");

        argsOrderList.add("-verbose");



        if (includes != null && includes.length() > 0) {

            argsOrderList.add("-subpackages");

            argsOrderList.add(includes);

        }



        if (excludes != null && excludes.length() > 0) {

            argsOrderList.add("-exclude");

            argsOrderList.add(excludes);

        }



        String[] args = argsOrderList.toArray(new String[argsOrderList.size()]);

        System.out.println(Arrays.toString(args));

		//执行 tools.jar 中的 javadoc 命令

        Main.execute(args);



        File file = new File(outputDir);

        if (!file.exists()) {

            file.mkdirs();

        }

        file = new File(file, new Date().toString() + ".txt");

        FileOutputStream outputStream = new FileOutputStream(file);

		//判断每个顶级 java class 是否有编写 @author 人,没有就筛出来写入一个文件记录

        ClassDoc[] classes = root.classes();

        if (classes != null) {

            for (int i = 0; i < classes.length; ++i) {

                if (classes[i].containingClass() == null && classes[i].isPublic()) {

                    Tag[] authorTags = classes[i].tags("author");

                    if (authorTags == null || authorTags.length == 0) {

                        String filename = classes[i].position().file().getAbsolutePath();

                        outputStream.write((filename+"\r\n").getBytes());

                    }

                }

            }

        }

        root = null;

        outputStream.flush();

        outputStream.close();

    }



    private static String list2formatString(List<String> srcs, String div) {

        StringBuilder stringBuilder = new StringBuilder();

        for (int index=0; index<srcs.size(); index++) {

            if (index > 0) {

                stringBuilder.append(div);

            }

            stringBuilder.append(srcs.get(index));

        }

        return stringBuilder.toString();

    }

} 

有了 javadoc 自定义工具类,接下来编写 gradle 自定义 task 即可。

[](

)编写自定义 gradle task 进行检查


//groovy 编写

class JavaDocCheckerTask extends DefaultTask {

    //自定义 task 的输入

    @Input

    List<String> includePackages



    @Input

    List<String> excludePackages


# **总结**

面试建议是,**一定要自信,敢于表达**,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。

以上就是蚂蚁技术四面和HR面试题目,**以下最新总结的最全**,范围包含最全MySQL、Spring、Redis、JVM等最全面试题和答案,仅用于参考

![一份还热乎的蚂蚁金服面经(已拿Offer)面试流程4轮技术面+1轮HR](https://img-blog.csdnimg.cn/img_convert/8ca53c9ab48d4730691b12b0df0ef144.png)

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](



    @Input

    List<String> excludePackages


# **总结**

面试建议是,**一定要自信,敢于表达**,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。

以上就是蚂蚁技术四面和HR面试题目,**以下最新总结的最全**,范围包含最全MySQL、Spring、Redis、JVM等最全面试题和答案,仅用于参考

[外链图片转存中...(img-l2JwmGt8-1631173584612)]

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](

)**
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值