ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:39.55KB ,
资源ID:16551664      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/16551664.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(java 运行期类型鉴定Word文档下载推荐.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

java 运行期类型鉴定Word文档下载推荐.docx

1、class Circle extends Shape public String toString() return Circle;class Square extends Shape Squareclass Triangle extends Shape Trianglepublic class Shapes public static void main(String args) ArrayList s = new ArrayList(); s.add(new Circle(); s.add(new Square(); s.add(new Triangle(); Iterator e = s

2、.iterator(); while(e.hasNext() (Shape)e.next().draw(); /:基础类可编码成一个interface(接口)、一个abstract(抽象)类或者一个普通类。由于Shape没有真正的成员(亦即有定义的成员),而且并不在意我们创建了一个纯粹的Shape对象,所以最适合和最灵活的表达方式便是用一个接口。而且由于不必设置所有那些abstract关键字,所以整个代码也显得更为清爽。每个衍生类都覆盖了基础类draw方法,所以具有不同的行为。在main()中创建了特定类型的Shape,然后将其添加到一个Vector。这里正是上溯造型发生的地方,因为Vecto

3、r只容纳了对象。由于Java中的所有东西(除基本数据类型外)都是对象,所以Vector也能容纳Shape对象。但在上溯造型至Object的过程中,任何特殊的信息都会丢失,其中甚至包括对象是几何形状这一事实。对Vector来说,它们只是Object。用nextElement()将一个元素从Vector提取出来的时候,情况变得稍微有些复杂。由于Vector只容纳Object,所以nextElement()会自然地产生一个Object句柄。但我们知道它实际是个Shape句柄,而且希望将Shape消息发给那个对象。所以需要用传统的(Shape)方式造型成一个Shape。这是RTTI最基本的形式,因为在

4、Java中,所有造型都会在运行期间得到检查,以确保其正确性。那正是RTTI的意义所在:在运行期,对象的类型会得到鉴定。在目前这种情况下,RTTI造型只实现了一部分:Object造型成Shape,而不是造型成Circle,Square或者Triangle。那是由于我们目前能够肯定的唯一事实就是Vector里充斥着几何形状,而不知它们的具体类别。在编译期间,我们肯定的依据是我们自己的规则;而在编译期间,却是通过造型来肯定这一点。现在的局面会由多形性控制,而且会为Shape调用适当的方法,以便判断句柄到底是提供Circle,Square,还是提供给Triangle。而且在一般情况下,必须保证采用多形

5、性方案。因为我们希望自己的代码尽可能少知道一些与对象的具体类型有关的情况,只将注意力放在某一类对象(这里是Shape)的常规信息上。只有这样,我们的代码才更易实现、理解以及修改。所以说多形性是面向对象程序设计的一个常规目标。然而,若碰到一个特殊的程序设计问题,只有在知道常规句柄的确切类型后,才能最容易地解决这个问题,这个时候又该怎么办呢?举个例子来说,我们有时候想让自己的用户将某一具体类型的几何形状(如三角形)全都变成紫色,以便突出显示它们,并快速找出这一类型的所有形状。此时便要用到RTTI技术,用它查询某个Shape句柄引用的准确类型是什么。11.1.1 Class对象为理解RTTI在Jav

6、a里如何工作,首先必须了解类型信息在运行期是如何表示的。这时要用到一个名为“Class对象”的特殊形式的对象,其中包含了与类有关的信息(有时也把它叫作“元类”)。事实上,我们要用Class对象创建属于某个类的全部“常规”或“普通”对象。对于作为程序一部分的每个类,它们都有一个Class对象。换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当地说,是保存在一个完全同名的.class文件中)。在运行期,一旦我们想生成那个类的一个对象,用于执行程序的Java虚拟机(JVM)首先就会检查那个类型的Class对象是否已经载入。若尚未载入,JVM就会查找同名的.class文件,并将其载入。所

7、以Java程序启动时并不是完全载入的,这一点与许多传统语言都不同。一旦那个类型的Class对象进入内存,就用它创建那一类型的所有对象。若这种说法多少让你产生了一点儿迷惑,或者并没有真正理解它,下面这个示范程序或许能提供进一步的帮助:SweetShop.java/ Examination of the way the class loader works.class Candy static System.out.println(Loading Candyclass Gum Loading Gumclass Cookie Loading Cookiepublic class SweetShop

8、inside main new Candy();After creating Candy try Class.forName(Gum catch(ClassNotFoundException e) e.printStackTrace(System.err); System.out.println( After Class.forName(Gum) new Cookie();After creating Cookie对每个类来说(Candy,Gum和Cookie),它们都有一个static从句,用于在类首次载入时执行。相应的信息会打印出来,告诉我们载入是什么时候进行的。在main()中,对象的创

9、建代码位于打印语句之间,以便侦测载入时间。特别有趣的一行是:Class.forName(该方法是Class(即全部Class所从属的)的一个static成员。而Class对象和其他任何对象都是类似的,所以能够获取和控制它的一个句柄(装载模块就是干这件事的)。为获得Class的一个句柄,一个办法是使用forName()。它的作用是取得包含了目标类文本名字的一个String(注意拼写和大小写)。最后返回的是一个Class句柄。该程序在某个JVM中的输出如下:inside mainLoading CandyAfter creating CandyLoading GumAfter Class.forN

10、ame()Loading CookieAfter creating Cookie可以看到,每个Class只有在它需要的时候才会载入,而static初始化工作是在类载入时执行的。非常有趣的是,另一个JVM的输出变成了另一个样子:520页下程序看来JVM通过检查main()中的代码,已经预测到了对Candy和Cookie的需要,但却看不到Gum,因为它是通过对forName()的一个调用创建的,而不是通过更典型的new调用。尽管这个JVM也达到了我们希望的效果,因为确实会在我们需要之前载入那些类,但却不能肯定这儿展示的行为百分之百正确。1. 类标记在Java 1.1中,可以采用第二种方式来产生Cl

11、ass对象的句柄:使用“类标记”。对上述程序来说,看起来就象下面这样:Gum.class;这样做不仅更加简单,而且更安全,因为它会在编译期间得到检查。由于它取消了对方法调用的需要,所以执行的效率也会更高。类标记不仅可以应用于普通类,也可以应用于接口、数组以及基本数据类型。除此以外,针对每种基本数据类型的封装器类,它还存在一个名为TYPE的标准字段。TYPE字段的作用是为相关的基本数据类型产生Class对象的一个句柄,如下所示:等价于 is equivalent to boolean.classBoolean.TYPEchar.classCharacter.TYPEbyte.classByte.

12、TYPEshort.classShort.TYPEint.classInteger.TYPElong.classLong.TYPEfloat.classFloat.TYPEdouble.classDouble.TYPEvoid.classVoid.TYPE11.1.2 造型前的检查迄今为止,我们已知的RTTI形式包括:(1) 经典造型,如,它用RTTI确保造型的正确性,并在遇到一个失败的造型后产生一个ClassCastException违例。(2) 代表对象类型的Class对象。可查询Class对象,获取有用的运行期资料。在C+中,经典的造型并不执行RTTI。它只是简单地告诉编译器将对象当作新

13、类型处理。而Java要执行类型检查,这通常叫作“类型安全”的下溯造型。之所以叫“下溯造型”,是由于类分层结构的历史排列方式造成的。若将一个Circle(圆)造型到一个Shape(几何形状),就叫做上溯造型,因为圆只是几何形状的一个子集。反之,若将Shape造型至Circle,就叫做下溯造型。然而,尽管我们明确知道Circle也是一个Shape,所以编译器能够自动上溯造型,但却不能保证一个Shape肯定是一个Circle。因此,编译器不允许自动下溯造型,除非明确指定一次这样的造型。RTTI在Java中存在三种形式。关键字instanceof告诉我们对象是不是一个特定类型的实例(Instance即

14、“实例”)。它会返回一个布尔值,以便以问题的形式使用,就象下面这样:if(x instanceof Dog)(Dog)x).bark();将x造型至一个Dog前,上面的if语句会检查对象x是否从属于Dog类。进行造型前,如果没有其他信息可以告诉自己对象的类型,那么instanceof的使用是非常重要的否则会得到一个ClassCastException违例。我们最一般的做法是查找一种类型(比如要变成紫色的三角形),但下面这个程序却演示了如何用instanceof标记出所有对象。Pets.javaclass Pet class Dog extends Pet class Pug extends D

15、og class Cat extends Pet class Rodent extends Pet class Gerbil extends Rodent class Hamster extends Rodent class Counter int i; /:在Java 1.0中,对instanceof有一个比较小的限制:只可将其与一个已命名的类型比较,不能同Class对象作对比。在上述例子中,大家可能觉得将所有那些instanceof表达式写出来是件很麻烦的事情。实际情况正是这样。但在Java 1.0中,没有办法让这一工作自动进行不能创建Class的一个Vector,再将其与之比较。大家最终

16、会意识到,如编写了数量众多的instanceof表达式,整个设计都可能出现问题。当然,这个例子只是一个构想最好在每个类型里添加一个static数据成员,然后在构建器中令其增值,以便跟踪计数。编写程序时,大家可能想象自己拥有类的源码控制权,能够自由改动它。但由于实际情况并非总是这样,所以RTTI显得特别方便。Using instanceof, all the pets can be counted:PetCount.java/ Using instanceof.public class PetCount static String typenames = Pet, DogPugCat,Roden

17、tGerbilHamster ; / Exceptions thrown out to console: public static void main(String args) throws Exception ArrayList pets = new ArrayList(); Class petTypes = ), for(int i = 0; i 15; i+) pets.add( petTypes (int)(Math.random()*petTypes.length) .newInstance(); catch(InstantiationException e) System.err

18、.println(Cannot instantiate throw e; catch(IllegalAccessException e) Cannot accessCannot find class HashMap h = new HashMap(); typenames.length; h.put(typenamesi, new Counter(); pets.size(); i+) Object o = pets.get(i); if(o instanceof Pet) (Counter)h.get().i+; if(o instanceof Dog) if(o instanceof Pu

19、g) if(o instanceof Cat) if(o instanceof Rodent) if(o instanceof Gerbil) if(o instanceof Hamster) System.out.println(pets.get(i).getClass(); typenamesi + quantity: + (Counter)h.get(typenamesi).i);1. 使用类标记PetCount.java示例可用Java 1.1的类标记重写一遍。得到的结果显得更加明确易懂:PetCount2.java/ Using class literals.public class

20、 PetCount2 / Class literals: Pet.class, Dog.class, Pug.class, Cat.class, Rodent.class, Gerbil.class, Hamster.class, / Offset by one to eliminate Pet.class: int rnd = 1 + (int)( Math.random() * (petTypes.length - 1); petTypesrnd.newInstance(); petTypes.length; h.put(petTypesi.toString(), new Counter(

21、);class Petclass Dogclass Pugclass Catclass Rodentclass Gerbilclass Hamster Iterator keys = h.keySet().iterator(); while(keys.hasNext() String nm = (String)keys.next(); Counter cnt = (Counter)h.get(nm); nm.substring(nm.lastIndexOf(.) + 1) + + cnt.i);在这里,typenames(类型名)数组已被删除,改为从Class对象里获取类型名称。注意为此而额外做的工作:例如,类名不是Getbil,而是c11.petcount2.Getbil,其中已包含了包的名字。也要注意系统是能够区分类和接口的。也可以看到,petTypes的创建模块不需要用一个try块包围起来,因为它会在编译期得到检查,不会象Class.forName()那样“掷

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1