您的位置:首页 > 编程语言 > Java开发

java编程思想读书笔记 第十四章 类型信息(上)

2016-10-17 21:44 204 查看
运行时类型信息可以使得在程序运行时发现和使用类型信息。Java在运行时识别对象和类信息的两种方式:一是RTTI,假定我们在编译时就知道了所有类型;二是“反射”机制,允许在运行时发现和使用类信息。

1、为什么需要RTTI

RTTI:Run-Time Type Identification,运行时对象类型识别。

在Java中,所有的类型转换都是在运行时进行正确性检查的。这也是RTTI名字的含义:在运行时,识别一个对象的类型。使用RTTI,你可以查下某个对象的引用所指向的对象的确切类型,然后选择或者剔除特例。

2、Class对象

Class包含了与类有关的信息,事实上Class对象就是用来创建类的所有的“常规”对象的。Java使用Class对象来执行其RTTI,即使你正在执行的是类似转型这样的操作。Class类还拥有大量的使用RTTI的其他方式。

每当编写并且编译了一个新类,就会产生一个Class对象(是被保存在.class文件中)。为了生成这个对象,运行这个程序的Java虚拟机将使用被称为“类加载器”的子系统。类加载器子系统可以包含一条类加载器链,但是只有一个原生类加载器。原生加载器通常从本地盘加载,加载的都是可信类,包括Java API类。

所有的类都是对其第一次调用时,动态加载到JVM,当程序创建第一个对类的静态成员的引用时,就会加载整个类。因此证明类的构造器也是类的静态方法。因此,使用new操作符创建类的新对象也会被当作对类的静态成员的引用。类加载器首先检查这个类的Class对象是否已经加载。如果尚未加载,默认类加载器就会根据类名查找.class文件。在这个类的字节码(.class文件)被加载时,它们会接受验证,以确保其没有被破坏,并且不包含不良代码。

Class类的一些方法:

forName(“类名”)返回一个Class对象的引用,主要被用作如果类没有被加载就加载它

getName()返回全限定的类名

getSimpleName()返回不含包名的类名

getCanonicalName() 返回全限定类名

getInterfaces()返回Class对象的接口们

getSuperclass()返回直接基类

newInstance()得到Object引用(实现“虚拟构造器”的一种途径,它允许你声明:“我不知道你的确切类型,但是无论如何都要争取”,newInstance()创建的类必须有默认构造器)

2.1 类字面常量

使用类字面常量可以生成对Class对象的引用。比如:Shapes.class

对于类字面常量,在编译时就会检查,更高效安全。类字面常量不仅可以应用于普通类,也可以应用于接口、数组以及基本数据类型。

当使用“.class”来创建对Class对象的引用时,不会自动地初始化该Class对象。为使用类而做准备工作包含的三个步骤:

1)加载 查找字节码,并创建class对象

2)链接 验证字节码,为静态域分配空间

3)初始化 如果该类有超类,对其初始化,执行静态初始化器和静态初始化块

初始化有效的实现了尽可能的“惰性”,使用.class语法来获得对类的引用并不会引发初始化。

如果一个static final是“编译期常量”,那么这个值不需要对整个类进行初始化就可以被读取。但是,如果只是将一个域设置为static和final的,还不足以确保这种行为,因为它不是一个编译期常量,这样还是会对类进行加载。如果一个static域不是final的,那么在对它访问时,总是要求在它被读取之前,要先进行链接(为这个域分配存储空间)和初始化(初始化存储空间)。

2.2 泛化的Class引用

Class引用总是指向某个Class对象,表示的是它所指对象的确切类型。使用泛型引用,可以限定class引用的类型,使其不能再指向其他类型,是的编译器强制执行额外的类型检查。普通的class引用没有这个限制。

Class c = Cat.class;

为了放松限制,可以使用通配符,符号为“?”,表示任何类型。使用通配符产生的class引用,可以指向其它类型。例如:

Class<?> intClass = int.class;


使用“?extends BaseType”,可以创建一个范围,表示该类或该类的子类。向Class添加泛型语法的原因是为了提供编译期类型检查。例如:

Class<? extends Number> bounded = int.class;


将泛型语法用于class对象,newInstance()将返回该对象的确切类型。

Class c = Cat.class;

Cat mimi = c.newInstance();

2.3 新的转型语法

cast()方法接受参数对象,并将其转型为Class引用的类型。要转成类型的对象 = cast(被转对象);

Cat c= new cat();

Class p = Pet.class;

Pet pet = p.cast(c);

这个方法很繁琐,除了极端罕见情况外几乎用不到,毕竟平时使用 Pet pet = (Pet)c; 简单一句就可以了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 编程 class 对象