小谈反射机制

来源:互联网 发布:ubuntu上安装mysql5.7 编辑:程序博客网 时间:2024/05/20 07:52

反射机制是java中经常用到的,特别是在J2EE框架中,基本上都会有用到它。

要弄清楚反射机制,首先要清除lang包中的两个类ClassLoader和Class。

ClassLoader:

我们知道java程序编译成class文件之后,就回杯load到code segment区,但是这个load的过程并不是一次性完成的。

首先,class文件不会一次性加载,而是会在需要的时候杯加载,也就是所谓的动态加载(static语句块加载后只执行一次)。在JDK中,会有很多种的classloader,如Bootstrap

 ClassLoader,Externsion ClassLoader,App ClassLoader等等,这些加载器(除了Bootstrap ClassLoader)都继承自ClassLoader,作用各不相同。

Bootstrap ClassLoader:这个是加载的基础类,主要就是加载的核心class(核心库):rt.jar,resources.jar...

Extension ClassLoader:顾名思义,这个就是用来加载ext路径下的class(拓展库)

App ClassLoader:负责加载当前java application的Classpath的所有类

Class Loader是一个非常注重等级尊严的家族,有很“森严”的等级制度。

先说下这3个类加载器的关系,Bootstrap ClassLoader是Extension ClassLoader的parenrt,Extension ClassLoader是App ClassLoader的parent,注意这里不是继承关系,这里的三个指的是对象之间的关系。可以理解为App ClassLoader对象中有一个引用指向Extension ClassLoader,而Extension ClassLoader对象有一个引用指向Bootstrap ClassLoader,而Bootstrap ClassLoader是没有parent的。(ClassLoader有getParent()方法可以测试)。


加载过程(加载机制):程序编译生成class文件,会首先被APP ClassLoader加载,他在加载之前会首先根据parent引用判断parent ClassLoade是否已经加载此类,如果加载了,他就不加载,如果没有加载,并且parent ClassLoade还有parent引用,会看他的上一级ClassLoader是否加载,如此下去,如果 都没有加载这个Class,App Classloder才会加载此类。这里也就是所谓的“森严”。举个例子,我们 声明一个String对象,他应该是被App ClassLoader加载,但是他会”咨询“他的parent ClassLoader有没有加载,因为在Bootstrap Classloder已经加载,所以不会被其他加载器加载。这种机制会使得封装很严密,很好的保护java程序。

Class

ClassLoader谈好之后,我们来聊聊Class,从面向对象的角度看,Class文件也就是一个一个的Class对象,这些Class对象中有各自的属性,各自的方法。再深入点,这些属性,方法也是一个一个的对象,在JDK中,也提供了代表属性和方法的类,在lang.reflect包里面,Filed类表示属性,Method表示方法。
我们在创建一个类A的新对象的时候,一般是这样的A a = new A(),然后调用这个类的方法,但是这样可拓展性很差,如果要换一个类的时候,代码要全部重新改过。这里就用到到了反射机制,我们可以这样写:Class c = Class.forName(A),这个方法是加载A类,获取类A的Class对象,然后Object o = c.newInstance()就可以得到这个类的实例化对象了,其实这里可以得类A的所有方法,属性,通过Class类的getMethod和getParameters方法。一般在工程中,把需要实例化的类直接写到配置文件中,而不是代码中,可以获得更好的可扩展性。这里动态生成了A类的对象o,如果要用的A中的方法m,这里就需要用到上一节说到的动态代理了,m.invoke(o)。

综上,java中的反射机制是一种动态机制,可以动态对类进行加载,实例化等等。在Struts,Hibernate,Spring等框架中都有用到,极大的发挥了其可拓展性和灵活性,这也是多态的表现形式,缺点就是执行的速度相对直接new对象会有点慢。

以上就是我了解的反射机制,若有问题,请见谅。




0 0
原创粉丝点击