实战Java的反射机制

 

  众所周知,Java要调用某个对象的方法首先需要对象实例化后才能调用。

  而实例化对象常见的就是new执行和spring(DI)的依赖注入了。

  Spring的DI其实就是以反射作为最基础的技术手段。

  

一、反射机制实战

  1.反射概念

  指项目在运行状态下,可以知道任意一个类所有属性和方法,并且能够调用它的任意一个方法来获取信息,将这种动态调用对象方法的功能叫java语言的反射机制。

 

  2.应用场景:

  生成动态代理,面向切片编程。(ps:这两种是最常见的使用场景。而我写这篇文章的时候,遇到的不是这两种需求,而是需要知道某个方法的返回值。情况如下:正式环境的对接接口返回值解析错误,对接厂家的项目升级的时候,接口返回值进行了改动却没有进行通知,但是生产环境又不能debug,日志刚刚好没记录返回值,对接厂家又刚刚好非常忙没空理我,为了预防日后类似的场景,需要知道某个方法的返回值,这时我就想到了反射机制)

 

  3.实例化

  正常情况下我们用new方式实例化对象需要两步,(1)引入包名:import xx.xx.xx。(2)然后new 对象类名。

  反射通过字符串实例化对象也是两步:(1)Class clazz = Class.forName("包名");相当于上面的第一步。(2)clazz.newInstance()

  4.代码实战

@RequestMapping("agent")
public ModelAndView agent(HttpServletRequest request) throws Exception {
   //返回值
   Object obj = null;
   ModelAndView mv = getAutoView();
   try {
      ISysUser user = ContextUtil.getCurrentUser();
      if (user==null)
               return getAutoView();
      String un =user.getFullname();
    //简单的权限判断,这判断可以根据实际情况来 ResultMessage resultMessage
= new ResultMessage(); if(un.equals("超级管理员")) { Class clazz = null; String action = request.getParameter("action"); mv.addObject("action", action); if (action==null || action.isEmpty()) return mv; Object object = null; if (action.contains(".")) { //获取对应包的class类 clazz = Class.forName(action); //找到IOC容器中的实例化 object = AppUtil.getBean(clazz); } else { object = AppUtil.getBean(action); } String method = request.getParameter("method"); mv.addObject("method", method); //参数类型 String param = request.getParameter("paramNum"); mv.addObject("paramNum", param); //参数值 String reqBody = request.getParameter("reqBody"); mv.addObject("reqBody", reqBody); if(!reqBody.isEmpty()) { JSONArray jsonArray = JSONArray.fromObject(reqBody); String[] params = param.split(";"); if (params.length == jsonArray.size()){ Object[] objects = new Object[params.length]; Class[] objMethods = new Class[params.length]; for (int i = 0; i < params.length; i++) { if (param.startsWith("java.lang.")) { Object objParam = jsonArray.get(i);
             //基础类型判断
if (param.equals("java.lang.Integer")){ String str = String.valueOf(objParam); Integer inv = Integer.parseInt(str); objects[i] = inv; } else if (param.equals("java.lang.Short")){ String str = String.valueOf(objParam); Short inv = Short.parseShort(str); objects[i] = inv; } else if (param.equals("java.lang.Long")){ String str = String.valueOf(objParam); Long inv = Long.parseLong(str); objects[i] = inv; } else if (param.equals("java.lang.Double")){ String str = String.valueOf(objParam); Double inv = Double.parseDouble(str); objects[i] = inv; } else if (param.equals("java.lang.Float")){ String str = String.valueOf(objParam); Float inv = Float.parseFloat(str); objects[i] = inv; } else if (param.equals("java.lang.Boolean")){ String str = String.valueOf(objParam); Boolean inv = Boolean.parseBoolean(str); objects[i] = inv; } else { objects[i] = objParam; } } else if (param.equals("java.util.Map")) { Map map = jsonArray.getJSONObject(i); objects[i] = map; }else { JSONObject jsonObject = jsonArray.getJSONObject(i); Object cls = Class.forName(params[i]).newInstance(); Object objParam = JsonUtil.jsonTurnObject(jsonObject, cls); objects[i] = objParam; } objMethods[i] = Class.forName(params[i]); } //获取想要执行的方法 Method md = object.getClass().getDeclaredMethod(method, objMethods); obj = md.invoke(object, objects);//执行方法 System.out.println(obj); } else return getAutoView(); } else { //获取想要执行的方法 Method md = object.getClass().getMethod(method); obj = md.invoke(object); System.out.println(obj); } } else { resultMessage.setMessage("你没有该权限!"); resultMessage.setResult(0); } } catch (Exception e) { e.printStackTrace(); throw e; } if (obj!=null){ System.out.println(obj.getClass().toString()); switch (obj.getClass().toString()){ case "class java.lang.String": break; case "class java.lang.Long": break; case "class java.lang.Integer": break; case "class java.lang.Short": break; case "class java.lang.Byte": break; case "class java.lang.Float": break; case "class java.lang.Double": break; case "class java.lang.Boolean": break; case "class java.lang.Char": break; default: obj = JSONArray.fromObject(obj); break; } } return mv.addObject("obj", obj); }

该工具类就是将json转为相对应的类对象。

public static <T> T jsonTurnObject(JSONObject json, T clazz) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Field[] field = clazz.getClass().getDeclaredFields(); //获取实体类的所有属性,返回Field数组
        for(int j=0 ; j<field.length ; j++){ //遍历所有属性
            String name = field[j].getName(); //获取属性的名字
//            System.out.println("attribute name:"+name);
            Object object = json.get(name);//获取json属性
            if (object != null) {
                name = name.substring(0,1).toUpperCase()+name.substring(1); //将属性的首字符大写,方便构造get,set方法
                Method fieldSetMet = clazz.getClass().getMethod("set"
                            + name, field[j].getType());

                String type = field[j].getGenericType().toString(); //获取属性的类型
                if(type.equals("class java.lang.String")){ //如果type是类类型,则前面包含"class ",后面跟类名
                    fieldSetMet.invoke(clazz, object);
                } else if (type.equals("class java.lang.Integer")){
                    String str = String.valueOf(object);
                    Integer inv = Integer.parseInt(str);
                    fieldSetMet.invoke(clazz, inv);
                } else if (type.equals("class java.lang.Short")){
                    String str = String.valueOf(object);
                    Short inv = Short.parseShort(str);
                    fieldSetMet.invoke(clazz, inv);
                } else if (type.equals("class java.lang.Long")){
                    String str = String.valueOf(object);
                    Long inv = Long.parseLong(str);
                    fieldSetMet.invoke(clazz, inv);
                } else if (type.equals("class java.lang.Double")){
                    String str = String.valueOf(object);
                    Double inv = Double.parseDouble(str);
                    fieldSetMet.invoke(clazz, inv);
                } else if (type.equals("class java.lang.Float")){
                    String str = String.valueOf(object);
                    Float inv = Float.parseFloat(str);
                    fieldSetMet.invoke(clazz, inv);
                } else if (type.equals("class java.lang.Boolean")){
                    String str = String.valueOf(object);
                    Boolean inv = Boolean.parseBoolean(str);
                    fieldSetMet.invoke(clazz, inv);
                }
            }
        }

        return clazz;
    }

页面:

<form id="testWebserviceForm" method="post" action="agent.ht">
        <table class="table table-striped table-hover table-bordered custom-table2" cellpadding="0" cellspacing="0" border="0" type="main">
            <tr>
                <th width="20%">包名: </th>
                <td colspan="3"><input type="text" id="action" name="action"  class="inputText" value="${action}"
                           validate="{required:false,maxlength:32}" placeholder="例:java.util.Map" /></td>
            </tr>
            <tr>
                <th width="20%">方法名: </th>
                <td colspan="3"><input type="text" id="method" name="method"  class="inputText" value="${method}"
                           validate="{required:false,maxlength:255}" placeholder="例:put" /></td>
            </tr>
            <tr>
                <th width="20%">参数类型: </th>
                <td colspan="3"><input type="text" id="paramNum" name="paramNum"  class="inputText" value="${paramNum}"
                           validate="{required:false,maxlength:255}" placeholder="例:java.lang.String(多个用;隔开)" /></td>
            </tr>
            <tr>
                <th width="20%">参数: </th>
                <td colspan="3">
                    <textarea id="reqBody" name="reqBody" class="inputText" rows="15" cols="50"
                              placeholder="例JSONArray:[{},{}]">${reqBody}</textarea>
                </td>
            </tr>
            <tr>
                <th width="20%">操作: </th>
                <td colspan="3">
                    <button class="btn btn-xs btn-circle blue save" type="submit"><i
                            class="fa fa-sticky-note"></i>提交</button>
                </td>
            </tr>
        </table>
    </form>

附上运行结果

 

posted @ 2018-11-14 17:09  程序猿中的小白  阅读(441)  评论(2编辑  收藏  举报