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

JAVA的反射机制与RTTI

2015-08-22 18:06 543 查看
JAVA编译期所作的工作是:检查某些语法规则以及将.java文件生成.class文件
JAVA运行期:进行.class文件的加载以及对象的创建

RTTI

RTTI含义是:运行时识别一个对象的类型,其对应的类就是Class对象,每一个JAVA类都对应一个Class对象(进行编译后,就是.class文件),这个对象被保存到同名的.class文件中。所能够识别的对象类型都是在已经加载到内存空间中的Class对象,并且已经创建了相应的对象。
运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息。多态(polymorphism)是基于RTTI实现的。RTTI的功能主要是由Class类实现的。Java中每个对象都有相应的Class类对象,因此,我们随时能通过Class对象知道某个对象“真正”所属的类。无论我们对引用进行怎样的类型转换,对象本身所对应的Class对象都是同一个。当我们通过某个引用调用方法时,Java总能找到正确的Class类中所定义的方法,并执行该Class类中的代码。由于Class对象的存在,Java不会因为类型的向上转换而迷失。这就是多态的原理

Reflection
JAVA的反射机制在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性

JAVA并非动态语言,但是反射机制使其具有动态特性:
可以于运行时加载、探知、使用编译期间完全不知道的classes。(这句话的理解就是,某个类在编译期间并没有参与编译,但是在运行期间可以通过反射机制探知该类的属性和方法。)换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。反射机制的前提是Class对象已经加载到内存空间,但是没有创建相应的对象,也就是说反射操作的是Class对象,熟知Class对象的内部完整构造(但是不包括Methods的定义),并且可以生成其相应的对象实体,或者对其fields设值,或者唤起其methods.用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the
ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

Class 介绍:

众所周知Java有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象。

Class 类十分特殊。它和一般类一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM
便自动产生一个Class 对象。如果您想借由“修改Java标准库源码”来观察Class 对象的实际生成时机(例如在Class的constructor内添加一个println()),这样是行不通的!因为Class并没有public constructor。

Class类的加载:当Java创建某个类的对象,比如Human类对象时,Java会检查内存中是否有相应的Class对象。如果内存中没有相应的Class对象,那么Java会在.class文件中寻找Human类的定义,并加载Human类的Class对象。在Class对象加载成功后,其他Human对象的创建和相关操作都将参照该Class对象。类加载器在类被第一次静态调用(比如一个静态方法,一个静态代码块或者new关键字调用构造器,注意contructors其实都是静态的)时会把那个对应的Class对象加载到内存中。

Class类有名的一个static方法是forName。Class.forName("classname
with packagepath");
通过这个静态方法返回的一个对类的Class对象的引用,用户可以在运行时动态得到大量关于这个类的信息,包括接口,父类,方法,静态成员,甚至是像newInstance()方法这样的一个实现“虚拟构造器”的一种方式。所谓的虚拟构造器,就是声明“我不知道你的确切类型,至少在编译期不知道,但是我就是要正确的创建你的一个对象”。

Java允许我们从多种管道为一个class生成对应的Class object。

Class object 诞生管道
示例:
1)运用getClass()
注:每个class 都有此函数
String str = "abc";
Class c1 = str.getClass();
2)运用Class.getSuperclass()
Button b = new Button();
Class c1 = b.getClass();
Class c2 = c1.getSuperclass();
3)运用static method------Class.forName()(最常被使用)
Class c1 = Class.forName ("java.lang.String");
Class c2 = Class.forName ("java.awt.Button");
Class c3 = Class.forName ("java.util.LinkedList$Entry");
Class c4 = Class.forName ("I");
Class c5 = Class.forName (".class");
4)运用primitive wrapper classes的TYPE 语法
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Character.TYPE;
Class c4 = Short.TYPE;
Class c5 = Integer.TYPE;
Class c6 = Long.TYPE;
Class c7 = Float.TYPE;
Class c8 = Double.TYPE;
Class c9 = Void.TYPE;
希望大家在看完后能够给一些建议,可能理解的时候有错误!大家互相进步!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: