众所周知,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>

附上运行结果

实战Java的反射机制的更多相关文章

  1. 浅谈Java的反射机制和作用

    浅谈Java的反射机制和作用 作者:Java大师 欢迎转载,转载请注明出处 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象 ...

  2. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  3. java的反射机制

    一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...

  4. Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别

    一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:   其中

  5. java笔记--反射机制之基础总结与详解

    一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...

  6. JAVA的反射机制学习笔记(二)

    上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了.自己的步伐全然被打乱了~不能继续被动下去.得又一次找到自己的节奏. 4.获取类的Constructor 通过反射机制得到 ...

  7. java笔录---反射机制(1)

    引言   为了方便记忆java的反射机制,在这里仔细的总结了一下.主要是怕以后忘记了,这样也方便回忆.因为最近利用空余时间深入的了解spring和Mybatis框架,   像spring中核心模块IO ...

  8. Java高新技术 反射机制

     Java高新技术 反射机制 知识概要:                   (1)反射的基石 (2)反射 (3)Constructor类 (4)Field类 (5)Method类 (6)用反射方 ...

  9. java的反射机制浅谈(转)

    原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...

随机推荐

  1. 机器审核图片学习(2)安装pornDetector所用环境-python、scikit-learn、opencv

    1.安装python 下载安装即可:最好是C盘 路径:https://www.python.org/ 将Python的安装路径加到path环境变量中,Python/Scripts加到path环境变量 ...

  2. 人工模拟获取latch

    人工模拟获取latch 任意地dump一latches结构文件: SQL> oradebug dump latches 10 ORA-00074: no process has been spe ...

  3. 使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题

    原文 使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题 虽然微软宣称 Windows 10 将是最后一个 Windows 版本,但由于年代跨越 ...

  4. 优秀开源项目之四:CrashRptProbe,查询程序奔溃的利器

    1.背景: 在开发人员进行项目开发和调试代码时,有一个非常困扰的问题,就是程序在调试运行过程中会莫名其妙地异常退出.由于导致异常退出的问题非常多,因此在面对这种无任何提示的异常退出时,开发人员会非常无 ...

  5. CSRF 专题

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造.      也被称为:one click attack/session riding(一 ...

  6. 搭建本地yum源和局域网yum源

    搭建本地yum源和局域网yum源 由于很多客户环境是专网,不允许连网,无法使用网上的各种yum源,来回拷贝rpm包安装麻烦,还得解决依赖问题.所以想着搭建个本地/局域网YUM源,方便安装软件. 1   ...

  7. php 将一个二维数组中两个相同的value 相同 指定值相加

    array(3) { [0]=> array(7) { ["mlid"]=> int(1) ["num"]=> int(1) ["c ...

  8. WPF属性(二)附加属性

    原文:WPF属性(二)附加属性 附加属性是说一个属性本来不属于某个对象,但由于某种需求而被后来附加上,也就是把对象放入一个特定环境后对象才具有的属性就称为附加属性,附加属性的作用就是将属性与数据类型解 ...

  9. C# 事件详解

    1.事件的本质是什么 答:事件是委托的包装器,就像属性是字段的包装器一样 2.为什么有了委托还有有事件 委托可以被访问就可以被执行,事件则只能在类的内部执行 3.事件要怎么声明 a.明一个委托 //委 ...

  10. 零元学Expression Blend 4 - Chapter 32 简单轻松的学会如何使用Visual States(上)

    原文:零元学Expression Blend 4 - Chapter 32 简单轻松的学会如何使用Visual States(上) Visual State Manager中文翻译为视觉状态管理器,这 ...