首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 反射實戰:類別方法提取器 ShowMethods 與 StreamTokenizer 整理輸出

     編輯:Java 相關知識

反射工具主要支援物件序列化、Java Beans、RMI 等特性,鮮少直接使用。但常需動態提取類別相關資訊——查看原始碼或文件只能看到該類別定義/覆寫的方法,基類資訊拿不到。反射可自動展示完整介面。

ShowMethods.java:基本版方法提取器

//: ShowMethods.java
import java.lang.reflect.*;
public class ShowMethods {
    static final String usage = "usage: \nShowMethods qualified.class.name\nTo show all methods in class or: \nShowMethods qualified.class.name word\nTo search for methods involving 'word'";
    public static void main(String[] args) {
        if(args.length < 1) { System.out.println(usage); System.exit(0); }
        try {
            Class c = Class.forName(args[0]);
            Method[] m = c.getMethods();
            Constructor[] ctor = c.getConstructors();
            if(args.length == 1) {
                for (int i = 0; i < m.length; i++) System.out.println(m[i].toString());
                for (int i = 0; i < ctor.length; i++) System.out.println(ctor[i].toString());
            } else {
                for (int i = 0; i < m.length; i++)
                    if(m[i].toString().indexOf(args[1]) != -1) System.out.println(m[i].toString());
                for (int i = 0; i < ctor.length; i++)
                    if(ctor[i].toString().indexOf(args[1]) != -1) System.out.println(ctor[i].toString());
            }
        } catch (ClassNotFoundException e) { System.out.println("No such class: " + e); }
    }
} ///:~

Class.getMethods()/getConstructors() 回傳 Method/Constructor 陣列。toString() 產生完整方法簽名字串。執行期提取資訊屬「反射」技術。

有趣實驗

執行 java ShowMethods ShowMethods 可見編譯器自動合成的預設公用建構子。若改為非 public 類別,合成建構子不會出現(自動獲得與類別相同存取權限)。

ShowMethodsClean.java:移除限定詞美化輸出

//: ShowMethodsClean.java
import java.lang.reflect.*;
import java.io.*;
public class ShowMethodsClean {
    // ... usage 同前 ...
    public static void main(String[] args) {
        // ... 取得 Class、Method[]、Constructor[] ...
        // 轉換為清理後字串陣列
        String[] n = new String[m.length + ctor.length];
        for(int i = 0; i < m.length; i++) {
            String s = m[i].toString();
            n[i] = StripQualifiers.strip(s);
        }
        for(int i = 0; i < ctor.length; i++) {
            String s = ctor[i].toString();
            n[i + m.length] = StripQualifiers.strip(s);
        }
        // ... 輸出或搜尋 ...
    }
}
class StripQualifiers {
    private StreamTokenizer st;
    public StripQualifiers(String qualified) {
        st = new StreamTokenizer(new StringReader(qualified));
        st.ordinaryChar(' '); // 保留空格
    }
    public String getNext() { /* ... 解析 token ... */ }
    public static String strip(String qualified) {
        StripQualifiers sq = new StripQualifiers(qualified);
        String s = "", si;
        while((si = sq.getNext()) != null) {
            int lastDot = si.lastIndexOf('.');
            if(lastDot != -1) si = si.substring(lastDot + 1);
            s += si;
        }
        return s;
    }
} ///:~

利用 StreamTokenizer 解析並移除 java.lang 等限定詞,輸出更易讀。第 17 章提供 GUI 版本供開發時快速查詢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved