方法尋找工具

來源:互聯網
上載者:User

第11章介紹了Java 1.1新的“反射”概念,並利用這個概念查詢一個特定類的方法——要麼是由所有方法構成的一個完整列表,要麼是這個列表的一個子集(名字與我們指定的關鍵字相符)。那個例子最大的好處就是能自動顯示出所有方法,不強迫我們在繼承結構中遍曆,檢查每一級的基礎類。所以,它實際是我們節省編程時間的一個有效工具:因為大多數Java方法的名字都規定得非常全面和詳盡,所以能有效地找出那些包含了一個特殊關鍵字的方法名。若找到符合標準的一個名字,便可根據它直接查閱線上說明文檔。
但第11的那個例子也有缺陷,它沒有使用AWT,僅是一個純命令列的應用。在這兒,我們準備製作一個改進的GUI版本,能在我們鍵入字元的時候自動重新整理輸出,也允許我們在輸出結果中進行剪下和粘貼操作:

 

//: DisplayMethods.java// Display the methods of any class inside// a window. Dynamically narrows your search.import java.awt.*;import java.awt.event.*;import java.applet.*;import java.lang.reflect.*;import java.io.*;public class DisplayMethods extends Applet {  Class cl;  Method[] m;  Constructor[] ctor;  String[] n = new String[0];  TextField     name = new TextField(40),    searchFor = new TextField(30);  Checkbox strip =     new Checkbox("Strip Qualifiers");  TextArea results = new TextArea(40, 65);  public void init() {    strip.setState(true);    name.addTextListener(new NameL());    searchFor.addTextListener(new SearchForL());    strip.addItemListener(new StripL());    Panel       top = new Panel(),      lower = new Panel(),      p = new Panel();    top.add(new Label("Qualified class name:"));    top.add(name);    lower.add(      new Label("String to search for:"));    lower.add(searchFor);    lower.add(strip);    p.setLayout(new BorderLayout());    p.add(top, BorderLayout.NORTH);    p.add(lower, BorderLayout.SOUTH);    setLayout(new BorderLayout());    add(p, BorderLayout.NORTH);    add(results, BorderLayout.CENTER);  }  class NameL implements TextListener {    public void textValueChanged(TextEvent e) {      String nm = name.getText().trim();      if(nm.length() == 0) {        results.setText("No match");        n = new String[0];        return;      }      try {        cl = Class.forName(nm);      } catch (ClassNotFoundException ex) {        results.setText("No match");        return;      }      m = cl.getMethods();      ctor = cl.getConstructors();      // Convert to an array of Strings:      n = new String[m.length + ctor.length];      for(int i = 0; i < m.length; i++)        n[i] = m[i].toString();      for(int i = 0; i < ctor.length; i++)        n[i + m.length] = ctor[i].toString();      reDisplay();    }  }  void reDisplay() {    // Create the result set:    String[] rs = new String[n.length];    String find = searchFor.getText();    int j = 0;    // Select from the list if find exists:    for (int i = 0; i < n.length; i++) {      if(find == null)        rs[j++] = n[i];      else if(n[i].indexOf(find) != -1)          rs[j++] = n[i];    }    results.setText("");    if(strip.getState() == true)      for (int i = 0; i < j; i++)        results.append(          StripQualifiers.strip(rs[i]) + "\n");    else // Leave qualifiers on      for (int i = 0; i < j; i++)        results.append(rs[i] + "\n");  }  class StripL implements ItemListener {    public void itemStateChanged(ItemEvent e) {      reDisplay();    }  }  class SearchForL implements TextListener {    public void textValueChanged(TextEvent e) {      reDisplay();    }  }  public static void main(String[] args) {    DisplayMethods applet = new DisplayMethods();    Frame aFrame = new Frame("Display Methods");    aFrame.addWindowListener(      new WindowAdapter() {        public void windowClosing(WindowEvent e) {          System.exit(0);        }      });    aFrame.add(applet, BorderLayout.CENTER);    aFrame.setSize(500,750);    applet.init();    applet.start();    aFrame.setVisible(true);  }}class StripQualifiers {  private StreamTokenizer st;  public StripQualifiers(String qualified) {      st = new StreamTokenizer(        new StringReader(qualified));      st.ordinaryChar(' ');  }  public String getNext() {    String s = null;    try {      if(st.nextToken() !=            StreamTokenizer.TT_EOF) {        switch(st.ttype) {          case StreamTokenizer.TT_EOL:            s = null;            break;          case StreamTokenizer.TT_NUMBER:            s = Double.toString(st.nval);            break;          case StreamTokenizer.TT_WORD:            s = new String(st.sval);            break;          default: // single character in ttype            s = String.valueOf((char)st.ttype);        }      }    } catch(IOException e) {      System.out.println(e);    }    return s;  }  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;  }} ///:~


程式中的有些東西已在以前見識過了。和本書的許多GUI程式一樣,這既可作為一個獨立的應用程式使用,亦可作為一個程式片(Applet)使用。此外,StripQualifiers類與它在第11章的表現是完全一樣的。
GUI包含了一個名為name的“文字欄位”(TextField),或在其中輸入想尋找的類名;還包含了另一個文字欄位,名為searchFor,可選擇性地在其中輸入一定的文字,希望在方法列表中尋找那些文字。Checkbox(複選框)允許我們指出最終希望在輸出中使用完整的名字,還是將前面的各種限定資訊刪去。最後,結果顯示於一個“文本地區”(TextArea)中。
大家會注意到這個程式未使用任何按鈕或其他組件,不能用它們開始一次搜尋。這是由於無論文字欄位還是複選框都會受到它們的“偵聽者(Listener)對象的監視。只要作出一項改變,結果清單便會立即更新。若改變了name欄位中的文字,新的文字就會在NameL類中捕獲。若文字不為空白,則在Class.forName()中用於嘗試尋找類。當然,在文字鍵入期間,名字可能會變得不完整,而Class.forName()會失敗,這意味著它會“擲”出一個違例。該違例會被捕獲,TextArea會隨之設為“Nomatch”(沒有相符)。但只要鍵入了一個正確的名字(大小寫也算在內),Class.forName()就會成功,而getMethods()和getConstructors()會分別返回由Method和Constructor對象構成的一個數組。這些數組中的每個對象都會通過toString()轉變成一個字串(這樣便產生了完整的方法或構建器簽名),而且兩個列表都會合并到n中——一個獨立的字串數組。數組n屬於DisplayMethods類的一名成員,並在調用reDisplay()時用於顯示的更新。
若改變了Checkbox或searchFor組件,它們的“偵聽者”會簡單地調用reDisplay()。reDisplay()會建立一個臨時數組,其中包含了名為rs的字串(rs代表“結果集”——Result Set)。結果集要麼直接從n複製(沒有find關鍵字),要麼選擇性地從包含了find關鍵字的n中的字串複製。最後會檢查strip Checkbox,看看使用者是不是希望將名字中多餘的部分刪除(預設為“是”)。若答案是肯定的,則用StripQualifiers.strip()做這件事情;反之,就將列表簡單地顯示出來。
在init()中,大家也許認為在設定布局時需要進行大量繁重的工作。事實上,組件的布置完全可能只需要極少的工作。但象這樣使用BorderLayout的好處是它允許使用者改變視窗的大小,並特別能使TextArea(文本地區)更大一些,這意味著我們可以改變大小,以便毋需滾動即可看到更長的名字。
編程時,大家會發現特別有必要讓這個工具處於運行狀態,因為在試圖判斷要調用什麼方法的時候,它提供了最好的方法之一。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.