之前也了解过java的反射机制,不过只是知道意思,而没有真正的去使用它,去进一步的他在什么时候去使用,这次在一个web项目中让我重新去认知了反射在我们程序中的重要性:
1.使我们的代码更加灵活
2.减少了我们代码之间的耦合性
3.代码的复用性更强
反射的基础使用
-------------------------------------------------------------------------------------------
1、反射所需要的类模块
java.lang.Class(用来描述类信息的类)
java.lang.Constructor(提供构造方法信息和对构造方法的访问)
java.lang.reflect.Field(类的属性信息)
java.lang.reflect.Method(类的方法信息)
java.lang.reflect.Modifier(解析类和方法的访问权限)
2.反射机制获取Class的方式
I、通过加载类的全称路径:Class class = Class.forName("类的路径");
II、通过对象中的getClass方法得到:Class class = p.getClass();ps:p为某一个类的实例化对象
III、通过类的class轻松拿到:Class class = 类名.class;
3.获取类属性
I、获取所有属性
Filed[] fs = class.getDeclaredFileds();//获取所有属性(包含private、protected、public)
Filed[] fs = class.getFileds();//获取所有公有的属性
注解:Field下面的方法就不一一写了,大家多用就知道了
II、获取指定属性
Field f = class.getDeclaredField("name");//通过属性名获取属性(包含private、protected、public)
Field f = class.getField("name");//获取公有的属性
Ps:总之,就是加上Declared给他面子把所有的都可以让获取,不加Declared就没有那个权限了
4.获取类方法
I、获取所有方法
Method[] ms = class.getDeclaredMethods();//同理
Method[] ms = class.getMethods();
II、获取指定方法
Method m = class.getDeclaredMethod("setName",String.class);//通过方法名和方法参数获取
Method m = class.getMethod("getName",null);
Ps:java中的源码为:getDeclaredMethod(String name,Class<T>[] Parameter);这样大家应该就很清楚了
5.总结
为什么用反射呢,那就是为了偷懒,在web项目中前台的参数如果很多,我们一个个获取并封装是不是有点太累了,我们对每一个对象都这么做的话,写个代码就要累死了,所有我就偷个懒自己写了个工具类,进行将参数转换为Bean的形式,现在我们开发中有好多的框架都帮我们做这些了,比如Struts2和SpringMvc等等,他们能够帮我们自动封装为对应对象的形式,不过偶尔自己写写会更好吧。。附上我自己写的http参数转换工具类,暂时还是菜鸟,有啥改进希望大家提出来
package com.wsq.crm.util;
/**
* Created by admin on 2017/7/27.
*/
import com.sun.javafx.webkit.prism.PrismInvoker;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.*;
/**
* 这是一个接受表单的参数,并将得到的参数封装为一个Bean对象
*/
public class RequestToBeanUtil {
/**
* turn方法的核心思想是找相同:req 和 tClass 一定用相同的部分,因为要将req中的参数值和cls的属性值进行自动设置
* @param req
* @param tClass
* @return
*/
public static final Object turn(HttpServletRequest req,Class tClass) throws InvocationTargetException {
Object obj = null;
try {
obj = tClass.newInstance();
Enumeration<String> em = req.getParameterNames();
while (em.hasMoreElements()){
String key = em.nextElement();
String val = req.getParameter(key);
//查找class中对应的setXXX方法
Method[] methods = tClass.getDeclaredMethods();
for (Method m: methods){
//忽略大小写
if(m.getName().equalsIgnoreCase("set"+key)){
Class pc[] = m.getParameterTypes();
if(pc[0].getName().equalsIgnoreCase("float")){
m.invoke(obj,Float.parseFloat(val));
break;
}else if (pc[0].getSimpleName().equalsIgnoreCase("int")){
m.invoke(obj,Integer.parseInt(val));
break;
}else if (pc[0].getSimpleName().equalsIgnoreCase("boolean")){
m.invoke(obj,Boolean.parseBoolean(val));
break;
}else if (pc[0].getSimpleName().equalsIgnoreCase("byte")){
m.invoke(obj,Byte.parseByte(val));
break;
}else if (pc[0].getSimpleName().equalsIgnoreCase("timestamp")){
m.invoke(obj, Timestamp.valueOf(val));
break;
}else{
m.invoke(obj,val);
break;
}
}
}
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return obj;
}
}