反射是Java实现模块化的一个非常基础的功能,通过加载类的字节码,然后动态的在内存中生成对象。也是深入Java 研究的第一个高级主题。关于加载器和字节码部分的内容,可以参见本博的 《java Class和加载机制精华一页纸》
Spring 框架基础的Ioc就是采用了反射的功能,实现了框架。
1、反射
I、反射操作经典步骤
一、获取 Class对象
a、最常用的就是 Class.forName(className)
b、如果知道类名字,直接通过类获取 String.class
c、如果已有一个对象 object.getClass
二、获取 Method对象
a、通过Class对象的getdeclaredMethods 获取所有方法
b、通过名字和参数类型列表,获取具体的方法getdeclaredMethod
三、实例化该Class的对象
Class.newInstance
四、调用方法
Method.invoke(newobject,new Object[]{parmalist}
II、反射的作用
反射是实现抽象的一个基础设施。单个应用内的模块化和解耦, 大家都比较熟悉, 比如 面向接口编程, 工厂模式等等。
iterface a = Factory.create;
在Factory 里面,我们是知道这个具体的实现类的。
但如果是应用模块之间呢, 不同人或者团队开发的, 商量好名字? 如果 名字改变后呢?
这样耦合性太强, 每次修改都会要带来代码重新修改和编译。
反射正是可以解决这个问题的工具。静态编译时, 并不需要知道具体的名字;在加载时, 通过传入名称参数, 获取到这个类
比如, 配置文件中配置了 具体实现类的名字, 只要在一个ClassPath下,就可以加载到具体的实现类。
Class c = Class.forName( param ); // 此处param可以是加载文件\其他应用传入的参数等等
iterface a = c.newInstance();
这个解耦套路,就是 传统的框架 套路
2、传统模块间解耦框架 - 依赖查找(DL)
依赖查找, 有个最经典的例子就是 JNDI , JavaEE