|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
而学习JAVA我觉得最应该避免的就是:只学习,不思考,只记忆,不实践!
本章的各类计划计划都在勉力制止利用RTTI,这也许会给人人留下“RTTI无害”的印象(还记得不幸的goto吗,因为给人印象欠安,基本就没有放到Java里来)。但实践情形并不是相对云云。准确地说,应当是RTTI利用不妥才“无害”。我们之以是想制止RTTI的利用,是因为它的毛病使用会形成扩大性遭到伤害。而我们事条件出的方针就是能向体系自在到场新范例,同时包管对四周的代码形成尽量小的影响。因为RTTI常被滥用(让它查找体系中的每品种型),会形成代码的扩大才能年夜打扣头——增加一种新范例时,必需找出利用了RTTI的一切代码。即便仅漏掉了个中的一个,也不克不及从编译器那边失掉任何匡助。
但是,RTTI自己其实不会主动发生非扩大性的代码。让我们再来看一看后面提到的渣滓接纳例子。这一次筹办引进一种新工具,我把它叫作TypeMap。个中包括了一个Hashtable(散列表),个中包容了多个Vector,但接口十分复杂:能够增加(add())一个新对象,能够取得(get())一个Vector,个中包括了属于某种特定范例的一切对象。关于这个包括的散列表,它的关头在于对应的Vector里的范例。这类计划计划的长处(依据LarryOBrien的倡议)是在碰到一种新范例的时分,TypeMap会静态到场一种新范例。以是不论甚么时分,只需将一种新范例到场体系(即便在运转时代增加),它也会准确无误地得以承受。
我们的例子一样创建在c16.Trash这个“包”(Package)内的Trash范例布局的基本上(并且那儿利用的Trash.dat文件能够照搬到这里来)。
- //:DynaTrash.java
- //UsingaHashtableofVectorsandRTTI
- //toautomaticallysorttrashinto
- //vectors.Thissolution,despitethe
- //useofRTTI,isextensible.
- packagec16.dynatrash;
- importc16.trash.*;
- importjava.util.*;
- //GenericTypeMapworksinanysituation:
- classTypeMap{
- privateHashtablet=newHashtable();
- publicvoidadd(Objecto){
- Classtype=o.getClass();
- if(t.containsKey(type))
- ((Vector)t.get(type)).addElement(o);
- else{
- Vectorv=newVector();
- v.addElement(o);
- t.put(type,v);
- }
- }
- publicVectorget(Classtype){
- return(Vector)t.get(type);
- }
- publicEnumerationkeys(){returnt.keys();}
- //Returnshandletoadapterclasstoallow
- //callbacksfromParseTrash.fillBin():
- publicFillablefiller(){
- //Anonymousinnerclass:
- returnnewFillable(){
- publicvoidaddTrash(Trasht){add(t);}
- };
- }
- }
- publicclassDynaTrash{
- publicstaticvoidmain(String[]args){
- TypeMapbin=newTypeMap();
- ParseTrash.fillBin("Trash.dat",bin.filler());
- Enumerationkeys=bin.keys();
- while(keys.hasMoreElements())
- Trash.sumValue(
- bin.get((Class)keys.nextElement()));
- }
- }///:~
复制代码
只管功效很强,但对TypeMap的界说长短常复杂的。它只是包括了一个散列表,同时add()包袱了年夜部分的事情。增加一个新范例时,那品种型的Class对象的句柄会被提掏出来。随后,使用这个句柄判别包容了那类对象的一个Vector是不是已存在于散列表中。如谜底是一定的,就提掏出谁人Vector,并将对象到场个中;反之,就将Class对象及新Vector作为一个“键-值”对到场。
使用keys(),能够失掉对一切Class对象的一个“列举”(Enumeration),并且可用get(),可经由过程Class对象猎取对应的Vector。
filler()办法十分风趣,由于它使用了ParseTrash.fillBin()的计划——不但能实验添补一个Vector,也能用它的addTrash()办法试着添补完成了Fillable(可添补)接口的任何工具。filter()必要做的全体事变就是将一个句柄前往给完成了Fillable的一个接口,然后将这个句柄作为参数传送给fillBin(),就象上面如许:
ParseTrash.fillBin("Trash.dat",bin.filler());
为发生这个句柄,我们接纳了一个“匿名外部类”(已在第7章报告)。因为基本不必要用一个已定名的类来完成Fillable,只必要属于谁人类的一个对象的句柄便可,以是这里利用匿名外部类长短常得当的。
对这个计划,要注重的一个中央是只管没有计划成对回类加以把持,但在fillBin()每次举行回类的时分,城市将一个Trash对象拔出bin。
经由过程后面那些例子的进修,DynaTrash类的年夜多半部分都应该十分熟习了。这一次,我们不再将新的Trash对象置进范例Vector的一个bin内。因为bin的范例为TypeMap,以是将渣滓(Trash)丢进渣滓筒(Bin)的时分,TypeMap的外部回类机制会当即举行得当的分类。在TypeMap里遍历并对每一个自力的Vector举行操纵,这是一件相称复杂的事变:
- Enumerationkeys=bin.keys();
- while(keys.hasMoreElements())
- Trash.sumValue(
- bin.get((Class)keys.nextElement()));
复制代码
就象人人看到的那样,新范例向体系的到场基本不会影响到这些代码,亦不会影响TypeMap中的代码。这明显是办理成绩最美满的计划。只管它的确严峻依附RTTI,但请注重散列表中的每一个键-值对都只查找一品种型。除此之外,在我们增添一种新范例的时分,不会堕入“健忘”向体系到场准确代码的为难地步,由于基本就没有甚么代码必要增加。
前些天,在CSDN上看到了一个消息,说是net网页编程网页编程AJAX成功在Linux上运行,这一点对我触动很大,而且引发了我许多感叹,所以想写出来分享一下。 |
|