Java反射机制
各位大拿:如果文章有错请各位指教!
反射在项目里的应用:Java的反射机制主要运用在一些框架里,可以通过反射机制动态的获得对象和调用方法,在项目里 action里运用了反射机制来执行特定的方法。如果不运用反射机制,那么在该项目里,一个动作类就必须定义一个action,(这是因为当HTTPServletRequest请求到来时,会自动执行动作类里的execute方法)那必然会使action动作类,非常的繁杂,但其实很多动作是一个模块里的操作,完全可以放到一个动作类里,然后通过反射机制动态获得动作类里的指定方法。这样做的好处非常明显,大大简化了项目代码结构,让整个项目更具模块性。
代码如下:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
AccountForm aform = (AccountForm) form;
String action = aform.getAction();
ActionForward forward = null;
Method method = null;
try {
method = (Method) this.getClass().getMethod(
action,
new Class[] { ActionMapping.class, AccountForm.class,
HttpServletRequest.class,
HttpServletResponse.class, BusinessFactory.class });
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
forward = (ActionForward) method.invoke(this, new Object[] {
mapping, aform, request, response});
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return forward;
}
当然,在很多开源框架上,Java反射机制也运用的很广,在框架上的具体运用还不是很清楚,有待以后研究。
在这篇文章里,我将介绍一些反射的基本语法和操作:并结合具体运用来进行介绍。
Java反射机制可以实现以下功能:
1. 在运行的时候获得任意对象的类:这个可能比较难以理解,但只需先记住这点,然后慢慢看代码和解说,多看几次就会有说领悟。
2. 根据需要,在运行时可构造任意一个类的对象。说道这里我觉得可以说有三个东西帮程序构造对象;第一个是大家最喜欢也是最熟悉的通过类本身创建一个对象。第二个是通过反射得到这个对象的Class(我觉得也可以这样说,获得这个对象对应的Class类的一个对象),然后通过Class调用newInstance()来构造这个对象所代表的类的一个新对象,必须注意的是,Class的newInstance()方法是不带参数的。如果要构造带指定参数的对象,则要用第三种方法。第三种方法也必须先获得这个对象对应Class类的一个对象,然后通过这个Class的对象调用getConstructor(Class[] cl)得到一个Constructor的对象,最后Constructor的对象再调用newInstance(Object[] objs)方法来构造带参数的对象。
3. 在运行时获得任意对象的方法,包括私有的方法和受保护的方法,但感觉即使能获得也没啥用处?如果有高人知道具体作用请告知。
4. 可在运行时获得任意对象的属性。包括私有属性
在上述介绍中提到一个Class类,该类和绝大多数类一样继承了Object类,但它同时也是一个非常个数的类。这个类的实体主要表示的是一个正在运行的对象的class和interface,这个比较好理解,但它还表示enum,array,primitive,Java Types等。Class类是在ClassLoader的defineClass()被调用时创建一个Class对象。它是一切反射机制的基础,可以这样说:没有Class就没有反射机制,java功能也就大打折扣。
通过类名构造对象:
如果是非基本类型,可通过如下几种方式获得Class类的对象
a. 对象.getClass()
b. 类名.Class
c. Class.forName(String className):注意这里传一个类名做参数
基本类型(包括封装类型):
a. Integer.Class
b. Integer.TYPE
代码如下:
无参:
Class cl=Class.forName(“类名”);
Object obj=cl.newInstance();
有参:
public Object getObject(String className, Object[] objs) throws Exception {
Class class=Class.forName(className);
Class[] classes=new Class[objs.length];
for(int i=0;i<objs.length;i++) {
classes[i]=objs[i].getClass();
}
Constructor con=class.getConstructor(classes);
Object obj=con.newInstance(objs);
return obj;
}
获取(或执行)某对象的方法:
public void invoke(Object obj, String methodName, Object[] objs) throws Exception {
Class class=obj.getClass();
Class[] classes=new Class[objs.length];
for(int i=0;i<objs.length;i++) {
classes[i]=objs[i].getClass();
}
Method method=class.getMethod(methodName, classes);
method.invoke(obj,objs);
//注意如果是要执行静态方法,则上面一行不需传obj 直接method.invoke(null,objs);
}
获取某对象的属性:
public Object getField(Object obj, String fieldName) throws Exception {
Class class=obj.getClass();
Field field=class.getField(fieldname);//或得到所有的共有属性getFields();
Object obj=field.get(obj);//获得指定对象该字段的值,以对象类型返回
return obj;
//如果是静态属性则只需field.get(class);
}
以上方法都不能获得超类的方法和属性,但可通过该Class对象获得超类的Class对象,通过获得的超类Class对象再获得方法和属性。可通过如下递归来完成:
public void getField(Class class){
Class cls=class.getSuperclass();
if(!cls.equals(Object.class)){
Field[] fields = cls.getFields();
getField(cls);
}
}