`
juiccee
  • 浏览: 9353 次
  • 性别: Icon_minigender_1
  • 来自: 昆明
最近访客 更多访客>>
社区版块
存档分类
最新评论

Thinking in Java 笔记:RTTI

阅读更多
RTTI即run-time type identification,当你只有一个指向对象的基类引用时,RTTI机制可以让你找出这个对象确切的类型.
在运行期获得对象和类的信息有两钟方式:
传统的RTTI,它假定我们在编译期和运行期已经知道了所有的类型
反射机制则允许我们在运行期获得类的信息.
使用(TYPE)进行强制类型转换是RTTI最基本的使用方式,在Java中,所以的类型转换都是在运行期检查的,这也是RTTI名字的来源,在运行期,识别一个对象的类型.
类型信息在运行期的表示,是由一个Class对象来完成,每个类都有一个Class对象,它包含了与类相关的信息,Class对象用来创建"常规"对象.
关于ClassLoader:ClassLoader负责装载(创建)类的对象,并让你可以获得并操作这个Class对象的引用.

[img]http://juiccee.iteye.com/upload/picture/pic/22097/ed599853-8dda-3bc9-b59e-271403eb58f3.gif [/img]
如上图,ClassLoader可以分为三类:
首先是引导(bootstrap)类装入器(也称作基本(primordial) 类装入器),它与其它ClassLoader不同,不能由 Java 代码实例化。(通常是因为它是作为 VM 本身的一部分实现的(使用C++实现)这个类装入器可以从启动的类路径装入核心系统类,通常是位于 jre/lib 目录的 JAR 文件。但是能用 -Xbootclasspath 命令行选项修改这个类路径.
扩展(extension) 类装入器(也称作标准扩展类装入器)是引导类装入器的一个孩子。它的主要职责是从扩展目录装入类,通常位于 jre/lib/ext 目录。这提供了简单地访问新扩展的能力,例如不同的安全扩展,不需要修改用户的类路径即可实现。
系统(system) 类装入器(也称作应用程序(application)类装入器)负责从 CLASSPATH 环境变量指定的路径装入代码。默认情况下,这个类装入器是用户创建的任何类装入器的父类。这也是 ClassLoader.getSystemClassLoader() 方法返回的类装入器。

[img]http://juiccee.iteye.com/upload/picture/pic/22099/88664499-24fd-36b3-9941-9d792fdf620f.gif [/img]
类装载器采用双亲委派模型。在建立用户自定义的类装载器时可以指定其双亲。如果没有指定,则默认的是把系统类装载器作为其双亲。如果向用户自定义的装载器的构造方法里传递null,则引导装载器就是双亲。
classloader依次从缓存,双亲,自己来寻找类。classloader首先判断要求它装入的类是否与过去装入的类相同。如果相同,就返回上次返回的类(即保存在缓存中的类)。如果不是,就把装入类的机会交给父类。这两步递归地以深度优先的方式重复。如果父类返回 null(或抛出 ClassNotFoundException),那么类装载器会在自己的路径中寻找类的源。
因为父类类装入器总是先得到装入类的机会,所以classloader装入的类最靠近根。这意味着所有核心引导类都是由引导装入器装入的,这就保证装入了类(例如java.lang.Object)的正确版本。这也可以让类装入器看到自己或父类或祖先装入的类,但是不能看到子女装入的类。
使用双亲委派模式,避免了重复加载,同时保证加载入系统的核心类不被其它自定义的类非法替换,实现了良好的安全性

动态加载:
在JVM加载类的时候,需要经过三个步骤,装载、连接、初始化。装载就是找到相应的class文件,读入JVM .加载由三个基本动作组成:
1 通过该类型的完全限定名产生一个代表该类型的二进制数据流
2 解析这个二进制数据流为方法区内的内部数据结构
3 创建一个表示该类型的java.lang.Class类的实例

连接又分三步,
第一步是验证class是否符合规格,
第二步是准备,就是为类变量分配内存同时设置默认初始值,
第三步就是解析(resloving),这步是可选的,下文的loadClass方法的第二个参数来判定是否需要解析,所谓的解析根据《深入JVM》这本书的定义就是根据类中的符号引用查找相应的实体,再把符号引用替换成一个直接引用的过程。

众所周知,java采用的是动态加载机制,既在第一次使用的时候(程序第一次调用该类的非常量的静态成员变量或静态方法的时候,需要注意的是构造函数是一个静态方法)加载该类,
加载由三个基本动作组成:
在程序第一次调用用该类的情况下,装载完成以后进行连接,初始化

类字面常量
使用类字面常量生成一个该类的类对象的应用,如ClassName.class
有九种预定义的 Class 对象,表示八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、float、double和void。
System.out.println(Boolean.class.isPrimitive());//false
		System.out.println(Boolean.TYPE.isPrimitive());//true
		System.out.println(boolean.class.isPrimitive());//true



有几种方法可以生成Class对象的引用.
Class.forname("className")调用 forName("X") 将导致命名为 X 的类被初始化
ClassLoader下有两个loadClass方法:Class<?> loadClass(String name) ;Class<?> loadClass(String name, boolean resolve),第二个参数判定是否需要解释
最后就是使用类字面常量,这种情况下初始化将延迟到程序第一次调用该类的非常量的(non-constant)静态成员变量或静态方法的时候.之所以是非常量的静态成员是因为如果一个static final是一个编译期常量,例如:staitc final int foo =47;则不会导致类被初始化.但并不是所有static final都是编译期常量,例如:staitc final int bar =random.nextInt(1000);总之,访问任何非编译期常量都回导致初始化.

带泛型的Class对象引用:
使用带泛型的Class对象引用,你可以具体的指定这个Class对象的类型约束,以提供编译期间的类型检查
public class GenericClassReferences {
  public static void main(String[] args) {
    Class intClass = int.class;
    Class<Integer> genericIntClass = int.class;
    genericIntClass = Integer.class; // Same thing
    intClass = double.class;
    // genericIntClass = double.class; // Illegal
  }
}

"?"通配符号
若要表示类型约束为任何Number类的子类的时,使用以下代码将报错
Class<Number> numberClass = int.class;

因为虽然Integer是Number的子类,但是Integer Class object的类型 不是 Number Class object 类型的字类
正确的写法应该是:
Class<? extends Number> numberClass = int.class

"?"是java generics的一部分,表示"anything"即使某个Class对象不包含任何具体的类型信息,也推荐使用Class<?>也不是单独使用Class.这表明你不是忘了约束类型.
声明为Class<T> type的class对象调用type.newInstance()返回一个类型为T的对象.
同样,要表示类型约束为某类的超类时应使用:
Class<? super FancyToy> up = FancyToy.class.getSuperClass();
而不是
//FancyToy inherite from Toy
Class<Toy> up =FancyToy.class.getSuperClass();//won't compile!

但在这种情况下,调用类型约束为<? super xxx>的class对象的newInstance()方法只能返回Object.
Class<? super FancyToy> up = FancyToy.class.getSuperClass();
up.newInstance();//返回Object

SE5中,Class类增加了一个新的方法:public T cast(Object obj),这个方法将一个对象强制转换成此 Class 对象所表示的类或接口。
Building b = new House();
    Class<House> houseType = House.class;
    House h = houseType.cast(b);
    h = (House)b; // ... or just do this.


Class有一个isInstance()此方法是 Java 语言 instanceof 运算符的动态等效方法。如果指定的 Object 参数非空,且能够在不引发 ClassCastException 的情况下被强制转换成该 Class 对象所表示的引用类型,则该方法返回 true;否则返回 false。
分享到:
评论

相关推荐

    了解魔术般的技巧:RTTI初学者指南.flv

    了解魔术般的技巧:RTTI初学者指南.flv

    Thinking in Java 中文第四版+习题答案

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的...

    Thinking in Java Fourth Edition

    ### 《Thinking in Java》第四版重要知识点概览 #### 第1章 对象入门 - **对象的概念**:介绍面向对象编程的基本概念,包括对象、类、实例等。 - **创建对象**:详解如何在Java中创建对象,包括使用`new`关键字。 -...

    Thinking_in_java(chapter10).pdf

    传统RTTI:在编译和运行时都完全知道类型的具体信息,如Java中的instanceof运算符。 b. 反射:仅依靠运行时信息发掘类型信息,提供了类型动态操作的能力,如通过Class类的对象来发现和使用类的信息。 知识点二:...

    Thinking in Java简体中文(全)

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 ...

    RTTI:Rtti(反思)实践

    在编程领域,RTTI(Run-Time Type Information,运行时类型信息)是一种强大的特性,它允许程序在运行时检查和操作对象的实际类型。RTTI通常在面向对象的语言中使用,如C++或Pascal,用于增强代码的灵活性和动态性。...

    JAVA_Thinking in Java

    2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 ...

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm ------------------------------------------------- 本教程由yyc,spirit整理 ------------------------------------------------- “Thinking in Java...

    Thinking in Java(中文版 由yyc,spirit整理).chm

    “Thinking in Java”详细目录   写在前面的话 引言 1. 前提 2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD-ROM 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 ...

    Delphi的RTTI机制文档

    **Delphi的RTTI机制详解** RTTI,全称Runtime Type Information(运行时类型信息),是编程语言中的一种特性,允许程序在运行时获取对象的类型信息。在Delphi中,RTTI是一个强大的工具,它使得开发者能够在运行时...

    Thinking in C++ 第二卷

    《Thinking in C++ 第二卷》是一本深入探讨C++编程语言的经典著作,由Bruce Eckel撰写,旨在帮助读者理解并掌握C++的核心概念和技术。这本书涵盖了C++的高级特性,包括模板、STL(Standard Template Library)、异常...

    RTTI.zip_DELPHI RTTI_delphi_rtti

    Delphi的运行时类型信息(Runtime Type Information,简称RTTI)是其强大的特性之一,它允许程序员在程序运行时获取对象或类的类型信息。在Delphi中,RTTI可以帮助我们进行动态类型检查、反射操作以及自动生成代码等...

    RTTI.rar_DELPHI RTTI

    在编程领域,特别是使用Delphi语言时,RTTI(运行时类型信息,Runtime Type Information)是一个非常重要的概念。RTTI允许程序在运行时获取对象的类型信息,这为动态编程和反射提供了强大的支持。本示例源码是针对...

    Thinking In C++ VolumeII.pdf

    ### Thinking in C++ Volume II: Key Knowledge Points #### Introduction 《Thinking in C++ Volume II》是C++领域的一本经典著作,由Bruce Eckel和Chuck Allison共同撰写。本书旨在帮助读者深入理解C++语言,并...

    RTTI.rar_rtti

    在压缩包中的“www.pudn.com.txt”可能是一个链接或者资源说明,而“RTTI”可能是讲RTTI的文本文件或笔记,可能包含了候老师的讲解内容,涵盖了RTTI的基本概念、用法、注意事项以及实例分析。 学习RTTI有助于深入...

    thinking in c++

    《C++编程思想》(第1版) 荣获1996年度《软件开发》杂志的图书震撼大奖 (Jolt Award...//www.shubulo.com/attachment.php?aid=35 book53.part2.rar http://www.shubulo.com/attachment.php?aid=36 Thinking in C++(2nd) ...

    Thinking in C++(B)

    《Thinking in C++》是由Bruce Eckel编著的一套经典的C++编程教程,分为两卷。卷B(也就是我们讨论的这一部分)通常在卷A的基础上深入探讨C++的高级特性,包括模板、STL(标准模板库)、异常处理、命名空间、运行时...

Global site tag (gtag.js) - Google Analytics