日期:2011-03-22 16:16:00 来源:本站整理
<b>RTTI有害吗</b>[Java编程]
本文“<b>RTTI有害吗</b>[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
本章的各种计划筹划都在勤奋避免利用RTTI,这大概会给大家留下“RTTI有害”的印象(还记得可怜的goto吗,由于给人印象不佳,根本就没有放到Java里来).但实际情形并非绝对如此.精确地说,应当是RTTI利用不当才“有害”.我们之所以想避免RTTI的利用,是由于它的错误应用会造成扩大性遭到侵害.而我们事前提出的目标就是能向系统安闲加入新范例,同时保证对四周的代码造成尽大概小的影响.由于RTTI常被滥用(让它查找系统中的每一种范例),会造成代码的扩大本领大打折扣——增添一种新范例时,必须找出利用了RTTI的全部代码.即便仅遗漏了此中的一个,也不能从编译器那边得到任何帮忙.
但是,RTTI本身并不会自动产生非扩大性的代码.让我们再来看一看前面提到的垃圾回收例子.这一次预备引入一种新工具,我把它叫作TypeMap.此中包含了一个Hashtable(散列表),此中包容了多个Vector,但接口非常简单:可以增添(add())一个新对象,可以得到(get())一个Vector,此中包含了属于某种特定范例的全部对象.关于这个包含的散列表,它的关键在于对应的Vector里的范例.这种计划筹划的长处(按照Larry O'Brien的倡议)是在碰到一种新范例的时刻,TypeMap会动态加入一种新范例.所以不管什么时刻,只要将一种新范例加入系统(即便在运行期间增添),它也会精确无误地得以承受.
我们的例子一样成立在c16.Trash这个“包”(Package)内的Trash范例构造的底子上(并且那儿利用的Trash.dat文件可以照搬到这里来).
//: DynaTrash.java // Using a Hashtable of Vectors and RTTI // to automatically sort trash into // vectors. This solution, despite the // use of RTTI, is extensible. package c16.dynatrash; import c16.trash.*; import java.util.*; // Generic TypeMap works in any situation: class TypeMap { private Hashtable t = new Hashtable(); public void add(Object o) { Class type = o.getClass(); if(t.containsKey(type)) ((Vector)t.get(type)).addElement(o); else { Vector v = new Vector(); v.addElement(o); t.put(type,v); } } public Vector get(Class type) { return (Vector)t.get(type); } public Enumeration keys() { return t.keys(); } // Returns handle to adapter class to allow // callbacks from ParseTrash.fillBin(): public Fillable filler() { // Anonymous inner class: return new Fillable() { public void addTrash(Trash t) { add(t); } }; } } public class DynaTrash { public static void main(String[] args) { TypeMap bin = new TypeMap(); ParseTrash.fillBin("Trash.dat",bin.filler()); Enumeration keys = 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举行操作,这是一件相当简单的事情:
就象大家看到的那样,新范例向系统的加入根本不会影响到这些代码,亦不会影响TypeMap中的代码.这明显是办理问题最圆满的筹划.固然它确切严重依靠RTTI,但请注意散列表中的每个键-值对都只查找一种范例.除此以外,在我们增添一种新范例的时刻,不会陷入“忘掉”向系统加入精确代码的尴尬地步,因为根本就没有什么代码需求增添.Enumeration keys = bin.keys(); while(keys.hasMoreElements()) Trash.sumValue( bin.get((Class)keys.nextElement()));
以上是“<b>RTTI有害吗</b>[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
- ·上一篇文章:筹划范式学习总结
- ·下一篇文章:<b>访谒器范式</b>
- ·中查找“<b>RTTI有害吗</b>”更多相关内容
- ·中查找“<b>RTTI有害吗</b>”更多相关内容
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论