在 scanListing() 内部,会打开源码文件,并将其转换成一个StreamTokenizer。根据Java 帮助文档,将
true 传递给 slashStartments()和 slashSlashments()的本意应当是剥除那些注释内容,但这样做似
乎有些问题(在Java 1。0 中几乎无效)。所以相反,那些行被当作注释标记出去,并用另一个方法来提取注
释。为达到这个目的,"/"必须作为一个原始字符捕获,而不是让StreamTokeinzer 将其当作注释的一部分对
待。此时要用ordinaryChar()方法指示StreamTokenizer 采取正确的操作。同样的道理也适用于点号
("。"),因为我们希望让方法调用分离出单独的标识符。但对下划线来说,它最初是被StreamTokenizer 当
作一个单独的字符对待的,但此时应把它留作标识符的一部分,因为它在 static final值中以 TT_EOF 等等
形式使用。当然,这一点只对目前这个特殊的程序成立。wordChars()方法需要取得我们想添加的一系列字
符,把它们留在作为一个单词看待的记号中。最后,在解析单行注释或者放弃一行的时候,我们需要知道一
638
…………………………………………………………Page 640……………………………………………………………
个换行动作什么时候发生。所以通过调用 eollsSignificant(true) ,换行符(EOL)会被显示出来,而不是
被StreamTokenizer 吸收。
scanListing()剩余的部分将读入和检查记号,直至文件尾。一旦 nextToken()返回一个 final static值—
—StreamTokenizer。TT_EOF ,就标志着已经抵达文件尾部。
若记号是个"/",意味着它可能是个注释,所以就调用eatments(),对这种情况进行处理。我们在这儿唯
一感兴趣的其他情况是它是否为一个单词,当然还可能存在另一些特殊情况。
如果单词是 class (类)或interface (接口),那么接着的记号就应当代表一个类或接口名字,并将其置入
classes和 classMap。若单词是 import或者package,那么我们对这一行剩下的东西就没什么兴趣了。其他
所有东西肯定是一个标识符(这是我们感兴趣的),或者是一个关键字(对此不感兴趣,但它们采用的肯定
是小写形式,所以不必兴师动众地检查它们)。它们将加入到 identMap。
discardLine()方法是一个简单的工具,用于查找行末位置。注意每次得到一个新记号时,都必须检查行末。
只要在主解析循环中碰到一个正斜杠,就会调用eatments()方法。然而,这并不表示肯定遇到了一条注
释,所以必须将接着的记号提取出来,检查它是一个正斜杠(那么这一行会被丢弃),还是一个星号。但假
如两者都不是,意味着必须在主解析循环中将刚才取出的记号送回去!幸运的是,pushBack()方法允许我们
将当前记号“压回”输入数据流。所以在主解析循环调用 nextToken()的时候,它能正确地得到刚才送回的
东西。
为方便起见,classNames()方法产生了一个数组,其中包含了 classes集合中的所有名字。这个方法未在程
序中使用,但对代码的调试非常有用。
接下来的两个方法是实际进行检查的地方。在 checkClassNames()中,类名从 classMap 提取出来(请记住,
classMap 只包含了这个目录内的名字,它们按文件名组织,所以文件名可能伴随错误的类名打印出来)。为
做到这一点,需要取出每个关联的 Vector,并遍历其中,检查第一个字符是否为小写。若确实为小写,则打
印出相应的出错提示消息。
在 checkIdentNames()中,我们采用了一种类似的方法:每个标识符名字都从identMap 中提取出来。如果名
字不在 classes 列表中,就认为它是一个标识符或者关键字。此时会检查一种特殊情况:如果标识符的长度
等于3 或者更长,而且所有字符都是大写的,则忽略此标识符,因为它可能是一个static final值,比如
TT_EOF。当然,这并不是一种完美的算法,但它假定我们最终会注意到任何全大写标识符都是不合适的。
这个方法并不是报告每一个以大写字符开头的标识符,而是跟踪那些已在一个名为reportSet()的Vector 中
报告过的。它将Vector 当作一个“集合”对待,告诉我们一个项目是否已在那个集合中。该项目是通过将文
件名和标识符连接起来生成的。若元素不在集合中,就加入它,然后产生报告。
程序列表剩下的部分由 main()构成,它负责控制命令行参数,并判断我们是准备在标准 Java 库的基础上构
建由一系列类名构成的“仓库”,还是想检查已写好的那些代码的正确性。不管在哪种情况下,都会创建一
个ClassScanner 对象。
无论准备构建一个“仓库”,还是准备使用一个现成的,都必须尝试打开现有仓库。通过创建一个File 对象
并测试是否存在,就可决定是否打开文件并在 ClassScanner 中装载 classes 这个Properties 列表(使用
load())。来自仓库的类将追加到由ClassScanner 构建器发现的类后面,而不是将其覆盖。如果仅提供一个
命令行参数,就意味着自己想对类名和标识符名字进行一次检查。但假如提供两个参数(第二个是〃…a〃),
就表明自己想构成一个类名仓库。在这种情况下,需要打开一个输出文件,并用 Properties。save()方法将
列表写入一个文件,同时用一个字串提供文件头信息。
17。2 方法查找工具
第 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。*;
639
…………………………………………………………Page 641……………………………………………………………
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:〃));
小说推荐
- 软件工程实践者的思想(PDF格式)
- -Page 1-大 道 至 简—软件工程实践者的思想周爱民(Aimingoo 著-Page 2-序2004 年 11 月初爱民(Aimingoo)第一次把他的书稿给我,我翻看了一下,第一反应讲的是感想。这不错,在技
- 最新章:第26章
- 深入浅出MFC第2版(PDF格式)
- -Page 1-Page 2-山高月小山高月小 水落石出水落石出山高月小山高月小 水落石出水落石出-Page 3-深入淺出MFC(第版 使用Visual C 5.0 MFC 4.2)Dissecting MFC(Second Edition Using Visual C 5.0 MFC 4.2)侯俊
- 最新章:第309章
- VB2008从入门到精通(PDF格式英文版)
- -Page 1(R)The eXperT’s Voice inBeginningVB 2008From Novice to ProfessionalChristian Gross-Page 2-Page 3-Beginning VB 2008From Novice to Professional■C
- 最新章:第214章
- C语言游戏编程从入门到精通(PDF格式)
- -Page 1-Page 2-Page 3-Page 4-Page 5-Page 6-Page 7-Page 8-Page 9-Page 10-Page 11-Page 12-Page 13-Page 14
- 最新章:第4章
- JMS简明教程(PDF格式)
- -Page 1-JMS1.1规范中文版卫建军2007‐11‐22-Page 2
- 最新章:第28章
- C语言实例教程(PDF格式)
- -Page 1-前 言Visual C+是开发运行于Windows 95和Windows NT环境下的Win32应用程序的可视化编程工具中最重要的成员之一,它为软件开发人员提供了完整的编辑、编译和调试工具和建立于Win32 API(ApplicationProgramming Interface)基
- 最新章:第143章
- 神祗之眼 (正式版)第7卷(全文完)作者:百里芜虚
- 第五十一章离12月25日的圣诞节还有两天,纽约已经换上了节日的盛装,几天前的一场大雪令整个城市一片银白。人们笑逐颜开,都纷纷开始为节日做准备,商家为了在节日打开销路纷纷推出各种优惠促销手段,纽约的大街小巷全都这样热闹。依沙那被老婆打发出来买过节要用的杂货,而女儿则和凯妮一起到百货商场去买衣服去了。对
- 最新章:第23章
- SQL语言艺术(PDF格式)
- -Page 1-SQLSSQQLL语言艺术内容介绍本书分为12章,每一章包含许多原则或准则,并通过举例的方式对原则进行解释说明。这些例子大多来自于实际案例,对九种SQL经典查询场景以及其性能影响讨论,非常便于实践,为你数据库应用维护人员阅读。资深 SQL 专家 Stéphane Faroult倾力打
- 最新章:第27章
- php程序设计简明教程(DOC格式)
- -Page 1-PHP 程序设计简明教程PHP 讲义 第 1 页 共 90 页-Page 2-目录序 4第一章 PHP 简介 6
- 最新章:第31章