使用jdk的sun java doc工具包獲取類中方法的參數註釋信息,方法簽名註釋信息,返回值註釋信息,方法上的註解信息

某日工作時需要將類中所有方法詳細信息收集到excel中,包括方法的參數註釋信息,方法簽名註釋信息,返回值註釋信息,方法上的註解信息,而我需要列舉的類方法有80 90個那不是累死人。突然想到曾經寫過通過javadoc獲取註釋信息的功能,而註解信息,通過jdk暴露出來的api 是獲取不到,需要另闢蹊路,經過研究我發現sun.javadoc中有註解的信息,只是沒有暴露出來,在他的com.sun.tools.javac.tree.JCTree.JCMethodDecl類中,我使用了反射私有屬性獲取到了該信息。現提供解決方案如下,供有需要的兄弟享用:

1、首先你使用sun.javadoc需要依賴jdk的tools.jar,在gradle中添加依賴

compile files("${System.properties['java.home']}/../lib/tools.jar")

2、代碼調用

 /**
     * 
     */
    @Test
    public void generateRestFullExcel() {
        com.sun.tools.javadoc.Main
            .execute(new String[] { "-doclet", Doclet.class.getName(), "-docletpath",
                Doclet.class.getResource("/").getPath(), "-encoding", "utf-8", "-classpath",
                "D:/xxx/bin;",
                "D:/xxx/xxx.java" });
        JSONArray datas = show();
        
        String[] title = { "方法名稱", "方法說明", "入參", "出參", "註解" };
        // 創建excel工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 創建工作表sheet
        HSSFSheet sheet = workbook.createSheet();
        // 創建第一行
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = null;
        // 插入第一行數據的表頭
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
        }
        
        Map<String, String> map = new HashMap<>();
        map.put("方法名稱", "engName");
        map.put("方法說明", "description");
        map.put("入參", "params");
        map.put("出參", "returnType");
        map.put("註解", "annotation");
        
        for (int j = 0; j < datas.size(); j++) {
            JSONObject obj = datas.getJSONObject(j);
            HSSFRow nrow = sheet.createRow(j + 1);
            for (int i = 0; i < title.length; i++) {
                HSSFCell ncell = nrow.createCell(i);
                ncell.setCellValue(obj.getString(map.get(title[i])));
            }
        }
        
        // 創建excel文件
        File file = new File("D:/xxx/xxx.xlsx");
        try {
            file.createNewFile();
            // 將excel寫入
            FileOutputStream stream = FileUtils.openOutputStream(file);
            workbook.write(stream);
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }


 /**  */
    private static RootDoc root;
    
    // 一個簡單Doclet,收到 RootDoc對象保存起來供後續使用
    // 參見參考資料6
    /**
     * 
     * @author 許暢
     * @since JDK1.7
     * @version 2019年5月24日 許暢 新建
     */
    public static class Doclet {
        
        /**
         * @param root1 xx
         * @return xx
         */
        public static boolean start(RootDoc root1) {
            JavaDocTest.root = root1;
            return true;
        }
    }
    
    /**
     * @return xx
     */
    public static JSONArray show() {
        ClassDoc[] classes = root.classes();
        JSONArray array = new JSONArray();
        for (int i = 0; i < classes.length; ++i) {
            System.out.println(classes[i]);
            System.out.println(classes[i].commentText());
            
            for (MethodDoc method : classes[i].methods()) {
                if (!method.isPublic()) {
                    continue;
                }
                JSONObject jsonMethod = new JSONObject();
                jsonMethod.put("engName", method.name());
                jsonMethod.put("description", method.commentText());
                jsonMethod.put("process", "用於" + method.commentText());
                Field treeField = ReflectionUtils.findField(method.getClass(), "tree");
                try {
                    treeField.setAccessible(true);
                    JCMethodDecl tree = (JCMethodDecl) treeField.get(method);
                    jsonMethod.put("annotation", tree.mods.annotations.toString());
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                
                AnnotationDesc[] annotations = method.annotations();
                for (AnnotationDesc annotationDesc : annotations) {
                    System.out.println(annotationDesc);
                }
                
                String returnTypeValue = method.tags("return").length > 0 ? method.tags("return")[0].text() : null;
                jsonMethod.put("returnType", returnTypeValue);
                System.out.println("方法返回值:" + returnTypeValue);
                
                System.out.println("方法名稱:" + method.name());
                System.out.println(method.commentText());
                ParamTag[] paramTags = method.paramTags();
                System.out.println("方法參數:");
                JSONArray params = new JSONArray();
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < paramTags.length; j++) {
                    if (j > 0) {
                        sb.append(",");
                    }
                    
                    ParamTag paramTag = paramTags[j];
                    JSONObject param = new JSONObject();
                    params.add(param);
                    param.put("engName", paramTag.parameterName());
                    sb.append(paramTag.parameterName());
                    sb.append(":");
                    param.put("description", paramTag.parameterComment());
                    sb.append(paramTag.parameterComment());
                    System.out.println(paramTag.parameterName());
                    System.out.println(paramTag.parameterComment());
                }
                jsonMethod.put("params", sb.toString());
                jsonMethod.put("parameters", params);
                array.add(jsonMethod);
            }
        }
        System.out.println(array);
        return array;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章