首页 > 代码库 > Java反射机制
Java反射机制
Class类
1)在面向对象的世界里,万事万物皆对象。Java语言中,静态的成员、普通数据类型不是对象,其他的都是对象。而普通数据类型采用了包装类进行了弥补。我们写的每一个类,类实例化后可以得到一个对象。那么,类是不是对象呢?类是谁的对象呢?类是哪个类的对象呢?我们说,万事万物皆对象,我们写的每一个类,我们所提供的每一个类,也是对象,类是java.lang.Class类的实例对象。比如,写一个A类,它是Class类的实例对象。我写一个Student类,它也是Class类的实例对象。表述这个有一句话叫做“There is a class named Class”。现在有一个类,名字就叫做类。现在有一个类,它的名字就是Class。那么它的实例是什么呢?我们的每一个对象所属的类,就是它的实例。
2)这个对象到底如何表示呢?我们现在要写一个案例,就是要表示Class类的实例,
class Foo{}
这个Foo类就是一个对象。万事万物皆对象。谁的对象?java.lang.Class的实例对象。
那么,Foo的实例对象如何表示?
Foo foo1 = new Foo();
那么,我们知道Foo这个类也是一个对象,Class类的实例对象,如何表示呢?
我们可以看到,Class类的构造:
/*Constructor. Only the Java Virtual Machine creates Class objects. */
private Class(){}
是私有的构造函数,在类的外部是不能访问的。我们没有办法来直接创建这个对象。
任何一个类都是Class的实例,这个实例对象有三种表示方式。
第一种方式: 实际也在告诉我们,任何一个类都有一个隐含的静态成员变量class
Class c1 = Foo.class;
第二种表达方式: 已经知道该类的对象通过getClass方法
Class c2 = foo1.getClass();
注意,这点很容易混淆。foo1代表的是Foo的实例对象,c1,c2代表的是Class的实例对象,但这个对象本身说明Foo这个类是一个实例对象。官网上的说明为c1,c2表示了Foo类的类类型(class type)。Foo类的类类型指的就是,Foo这个类本身它就是一个对象,哪个类的对象?Class类的对象。我们说类类型指的是本身自己就是一个Class类的实例。但是Foo这个类本身也有实例对象,那就是Foo这个类的实例对象。这就和Foo类的类类型进行分开了。类类型指的是万事万物皆对象,类也是一个对象。这个对象,我们把它称之为类类型。
c1 == c2 //true
不管c1 or c2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象。
如果知道类名的话,可以采用.class,如果知道对象的话可以采用getClass()
第三种表达方式:
Class c3 = null;
try{
c3 = Class.forName("com.reflext.Foo"); //这里是类的全称,包含了package在内
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
c2 == c3 // true
以上把Class的概念弄清楚了。
我们完全可以通过类的类型创建该类的对象实例。也就是通过c1 or c2 or c3创建Foo的实例
这个c1如果是A类的类类型,那么创建出来的就是A类的实例对象,如果是B类的类类型,那么创建出来的就是B类的实例对象。现在它是Foo类的类类型,那么创建出来的就是Foo类的实例对象。
所以这个地方需要做强制类型转换。
Foo foo = (Foo)c1.newInstance(); //需要有无参数的构造方法
动态加载类
Class.forName("类的全称")
不仅表示了类的类型,还代表了动态加载类
一定要区分编译,运行
编译时刻加载类是静态加载类,运行时刻加载类是动态加载类
class Office { public sataic void main(String[] args) {
if("Word".equals(arg[0])){
Word w = new Word();
w.strat();
}
if("Excel".equals(arg[0])){
Excel e = new Excel();
e.strat();
}
} }
如果编译这个程序,会发现报错,提示两个类和两个方法找不到。如果再写一个Word类并编译,那么回头编译Office,仍然会提示2个错误,Excel类和run方法找不到。这是因为:new创建对象 是静态加载类,在编译时刻就需要加载所有的可能使用到的类。即便不适用Excel,即便Word已经存在,仍然无法使用Office程序。那么在实际应用中,我们当然希望Word存在,Word就能够使用,而现在Word虽然存在,却因为Excel不存在,造成了Word无法使用。如果将来有100个功能,只要有一个功能有问题,那么就会造成另外的99个功能不能使用,显然,这种情形不是我们所希望看到的。我们所希望看到的功能是,你用哪个,就加载哪个。不用不加载。所以我们希望在运行时进行加载。通过动态加载类,可以解决该问题。
Java反射机制