Java进阶教程之运行时类型识别RTTI机制
运行时类型识别(rtti, run-time type identification)是java中非常有用的机制,在java运行时,rtti维护类的相关信息。
多态(polymorphism)是基于rtti实现的。rtti的功能主要是由class类实现的。
class类
class类是"类的类"(class of classes)。如果说类是对象的抽象和集合的话,那么class类就是对类的抽象和集合。
每一个class类的对象代表一个其他的类。比如下面的程序中,class类的对象c1代表了human类,c2代表了woman类。
public class test
{
public static void main(string[] args)
{
human aperson = new human();
class c1 = aperson.getclass();
system.out.println(c1.getname());
human anotherperson = new woman();
class c2 = anotherperson.getclass();
system.out.println(c2.getname());
}
}
class human
{
/**
* accessor
*/
public int getheight()
{
return this.height;
}
/**
* mutator
*/
public void growheight(int h)
{
this.height = this.height + h;
}
private int height;
}
class woman extends human
{
/**
* new method
*/
public human givebirth()
{
system.out.println("give birth");
return (new human());
}
}
当我们调用对象的getclass()方法时,就得到对应class对象的引用。
在c2中,即使我们将women对象的引用向上转换为human对象的引用,对象所指向的class类对象依然是woman。
java中每个对象都有相应的class类对象,因此,我们随时能通过class对象知道某个对象“真正”所属的类。无论我们对引用进行怎样的类型转换,对象本身所对应的class对象都是同一个。当我们通过某个引用调用方法时,java总能找到正确的class类中所定义的方法,并执行该class类中的代码。由于class对象的存在,java不会因为类型的向上转换而迷失。这就是多态的原理。
getclass: 我是谁?
除了getclass()方法外,我们还有其他方式调用class类的对象。
public class test
{
public static void main(string[] args)
{
class c3 = class.forname("human");
system.out.println(c1.getname());
class c4 = woman.class
system.out.println(c2.getname());
}
}
上面显示了两种方式:
1.forname()方法接收一个字符串作为参数,该字符串是类的名字。这将返回相应的class类对象。
2.woman.class方法是直接调用类的class成员。这将返回相应的class类对象。
class类的方法
class对象记录了相应类的信息,比如类的名字,类所在的包等等。我们可以调用相应的方法,比如:
getname() 返回类的名字
getpackage() 返回类所在的包
可以利用class对象的newinstance()方法来创建相应类的对象,比如:
human newperson = c1.newinstance();
newinstance()调用默认的不含参数的构建方法。
我们可以获得类定义的成员:
getfields() 返回所有的public数据成员
getmethods() 返回所有的public方法
可以进一步使用reflection分析类。这里不再深入。
class类更多的方法可查询官方文档:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/class.html
class类的加载
当java创建某个类的对象,比如human类对象时,java会检查内存中是否有相应的class对象。
如果内存中没有相应的class对象,那么java会在.class文件中寻找human类的定义,并加载human类的class对象。
在class对象加载成功后,其他human对象的创建和相关操作都将参照该class对象。