《Java 编程思想》--第十四章:类型信息

  1. 运行时的类型信息使得你可以在程序运行时发现和使用类型信息
  2. 运行时识别对象和类的信息,主要有两种方式:
    1. 传统的RTTI,它假定我们在编译时已经知道了所有的类型
    2. 反射机制,允许我们在运行时发现和使用类的信息
  3. 在java中所有类型转换都是在运行时进行正确性检查的,这也就是在RTTI的含义:在运行时,识别一个对象的类型
  4. Class对象相关知识:
    1. java使用Class对象来执行其RTTI
    2. 类是程序的一部分,每个类都有一个Class对象,也就是说,每当编写并且编译了一个新类,就会产生一个Class对象(更恰当的说,是被保存在一个同名的.class文件中),为了生成这个对象,运行这个程序的Java虚拟机将使用被称为“类加载器”的子系统
    3. 类加载器子系统实际上可以包含一条类加载器链,但是只有一个原生类加载器,它是JVM实现的一部分。原生类加载器加载的是所谓的可信类,包括java api类,它们通常是从本地盘加载的。如果需要特殊需求,可以挂接额外的类加载器。
    4. 所有的类都是在对其第一次使用时,动态加载到JVM中的,static初始化实在类加载时进行的,当程序创建第一个对类的静态成员的引用时,就会加载这个类,这也证明了构造器是类的静态方法
    5. 类加载器首先检查着各类的Class对象是否已经加载,如果尚未加载,默认的类加载器就会根据类名查找.class文件
    6. Class类的static方法Class.forName():
      1. 取得Class对象的引用的一种方法
      2. 使用String作输入参数,返回的是一个Class对象的引用
      3. 如果找不到需要加载的类,会抛出异常ClassNotFoundException
      4. 传递给forName()的字符串中,必须使用全限定名
    7. Object中有getClass()方法来获得Class引用,它将返回对象的实际类型的Class引用
    8. Class中:
      1. getInterfaces()方法返回的是Class对象的所包含的接口
      2. getSuperclass()方法查询器直接基类
      3. newInstance()来创建类的实例
    9. Java还提供了另一种方法来生成对Class对象的引用,即使用类字面常量如:FancyToy.class
    10. 当使用.class来创建对象的引用时,不会自动地初始化该Class对象,为了使用类而做的准备工作实际包含三个步骤:
      1. 加载:这是由类加载器执行的,这里将查找字节码(通常在classpath所指定的路径中查找),并从这些字节码中创建一个Class对象
      2. 链接:在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用
      3. 初始化:如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块
    11. Class引用总是执行某个Class对象,它可以制造类的实例,并包含可作用于这些实例的所有方法代码。它还包含该类的静态成员
    12. 如果需要使用泛化的Class引用时,可以使用Class<>
      1. Java SE5中Class<?>匹配任意的类,Class<?>优于平凡的Class,即便他们是等价的
      2. 可以使用Class<? extends Number>来创建一个范围
      3. Class引用添加泛型语法的原因仅仅是因为为了提供编译期类型检查
      4. 当使用泛型语法用于Class对象时,newInstance()将返回该对象的确切类型,而不仅仅是基本的Object
      5. Class<? super FancyToy>允许声明超类引用是“某个类,它是FancyToy超类”
    13. Java SE5中添加了用于Class引用的转型语法,cast()
      1. cast()方法接收参数对象,并将其转型为Class引用的类型
      2. 使用方法   Class houseType;   House h = houseType.cast(b);  
  5. 已知的RTTI形式:
    1. 传统的类型转换,由RTTI确保类型转换的正确性,如果执行了一个错误的类型转换,就会抛出一个ClassCasetException异常
    2. 代表对象的类型Class对象,通过查询Class对象可以获取运行时所需的信息
    3. 使用instanceof,它将返回一个布尔值,告诉我们对象是不是某个特定类型的实例
  6. 对instanceof 有比较严格的限制:只可将其与命名类型进行比较,而不能与Class对象作比较
  7. 可以使用obj.isInstance(Obj)来判定obj是否是Obj类型的实例
  8. 如果不知道某个对象的确切类型,RTTi可以告诉你,但是有一个限制:这个类型在编译时必须已知,这样才能使用RTTI识别它,并列用这些信息做一些有用的事,换句话说,在编译时,编译器必须知道所有要通过RTTI来处理的类
  9. Class类与java.lang.reflect类库一起对反射的概念进行了支持,该类库包含了Field,Method,以及Constructor类(每个类都实现了Member接口)。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员
    1. 可以使用Constructor创建新的对象
    2. 用get()和set()方法读取和修改与Field对相关连的字段
    3. 用invoke方法调用与Method对相关联的方法
    4. 调用getFields()、getMethods()和getConstructors()来获得字段,方法,构造器的数组
  10. RTTI和反射之间的真正区别是:对于RTTI来说,编译器在编译时打开和检查.class文件,而对于反射机制来说,.class 文件在编译时是不可获取的,所以在运行时打开和检查.class方法
  11. 在使用内置的null表示缺少对象时,在每次使用引用都必须测试其是否为null。有时引用空对象的思想将会很有用,通过这种方式,可以假设所有的对象都是有效的
    1. 空对象定义在类呃内部,实现Null接口
    2. 空对象使用了单例模式,可以使用equals甚至==来比较Person.Null
  12. interface关键字的一种重要目标就是允许程序员隔离构建,进而降低耦合性
  13. 通过使用反射,可以到达并调用所以方法,甚至是private方法,如果知道方法名,可以在Method对象上杜鳌用setAccessible(true)
  14. 对于final域,修改时是安全的,运行时系统会在不抛异常的情况下接收任何修改尝试,但是实际上不会发生任何修改
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值