下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

快速了解java中的反射概念是由什么样的方法构成的

作者:课课家教育     来源: http://www.kokojia.com点击数:863发布时间: 2016-02-29 20:02:57

标签: java特定类java继承java基础类

大神带你学编程,欢迎选课

  java介绍了新的“反射”概念,并利用这个概念查询一个特定类的方法——要么是由所有方法构成的一个完整列表,要么是这个列表的一个子集(名字与我们指定的关键字相符)。那个例子最大的好处就是能自动显示出所有方法,不强迫我们在继承结构中遍历,检查每一级的基础类。所以,它实际是我们节省编程时间的一个有效工具:因为大多数Java方法的名字都规定得非常全面和详尽,所以能有效地找出那些包含了一个特殊关键字的方法名。若找到符合标准的一个名字,便可根据它直接查阅联机帮助文档。

快速了解java中的反射概念是由什么样的方法构成的_java特定类_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(文本区域)更大一些,这意味着我们可以改变大小,以便毋需滚动即可看到更长的名字。

  编程时,大家会发现特别有必要让这个工具处于运行状态,因为在试图判断要调用什么方法的时候,它提供了最好的方法之一。

赞(11)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程