1. 程式人生 > >java:通過javadoc API讀取java原始碼中的註釋資訊(comment)

java:通過javadoc API讀取java原始碼中的註釋資訊(comment)

如何從java原始碼中讀取註釋資訊?(注意不是指通過反射讀取annotation類,是comment,就是程式設計師在原始碼中加的註釋)
比如:

    /**
     * 使用當前類的class loader載入工具物件
     * @param classname
     * @return
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */

大概很少會有人需要用到這個,不過最近的專案中需要對自動生成的程式碼中加入原始程式碼的註釋,就需要從原始程式碼中獲取註釋。所以需要在程式實現讀取原始碼中的註釋資訊,網上找了很多文章都想通過分析原始碼檔案(正則表示式)來把註釋提取出來,差點被這些文章帶到坑裡,休息的時候突然想如果javadoc有API可以呼叫,應該就能通過javadoc來獲取完整的註釋,而不用自己費力去搞。
google一查,果然javadoc有API的,就在$JAVA_HOME/lib/tools.jar

中,官網也提供了完整的文件告訴你如何定製自己的javadoc輸出。最關鍵的一點就是提供一個Doclet 類,利用-doclet引數去替換掉javadoc預設的Doclet,然後你的Doclet類就能獲得一個包含完整豐富的結構化資訊的註釋物件RootDoc.然後你想怎麼玩就隨你啦。

關於如何在maven中將$JAVA_HOME/lib/tools.jar新增到dependency,參見 參考資料2

package gu.doc;

import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.RootDoc;

public
class JavaDocReader { private static RootDoc root; // 一個簡單Doclet,收到 RootDoc物件儲存起來供後續使用 // 參見參考資料6 public static class Doclet { public Doclet() { } public static boolean start(RootDoc root) { JavaDocReader.root = root; return true; } } // 顯示DocRoot中的基本資訊
public static void show(){ ClassDoc[] classes = root.classes(); 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()){ System.out.printf("\t%s\n", method.commentText()); } } } public static RootDoc getRoot() { return root; } public JavaDocReader() { } public static void main(final String ... args) throws Exception{ // 呼叫com.sun.tools.javadoc.Main執行javadoc,參見 參考資料3 // javadoc的呼叫引數,參見 參考資料1 // -doclet 指定自己的docLet類名 // -classpath 引數指定 原始碼檔案及依賴庫的class位置,不提供也可以執行,但無法獲取到完整的註釋資訊(比如annotation) // -encoding 指定原始碼檔案的編碼格式 com.sun.tools.javadoc.Main.execute(new String[] {"-doclet", Doclet.class.getName(), // 因為自定義的Doclet類並不在外部jar中,就在當前類中,所以這裡不需要指定-docletpath 引數, // "-docletpath", // Doclet.class.getResource("/").getPath(), "-encoding","utf-8""-classpath", "D:/j/facelog/facelog-main/target/classes;D:/j/facelog/db/target/classes;D:/j/facelog/db/sql2java/lib/swift-annotations-0.14.2.jar", // 獲取單個程式碼檔案FaceLogDefinition.java的javadoc "J:/facelog/facelog-main/src/main/java/net/gdface/facelog/FaceLogDefinition.java"}); show(); } }

參考資料