获取对象属性类型、属性名称、属性值的研究:反射和JEXL解析引擎
同步发布:http://www.yuanrengu.com/index.php/20170511.html
先简单介绍下反射的概念:java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以在运行时装配。在实际的业务中,可能会动态根据属性去获取值。
工具类如下:
package com.yaoguang.common.utils.field; import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* 实体属性操作工具类
*
* @author heyonggang
* @date 2017年5月10日下午5:56:59
*/
public class ObjectFieldUtil { private static Logger log = LoggerFactory.getLogger(ObjectFieldUtil.class); /**
* 根据属性名获取属性值
*
* @param fieldName 字段名
* @param o 实体
* @return
*/
public static Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[] {});
Object value = method.invoke(o, new Object[] {});
return value;
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
} /**
* 获取属性名数组
*
* @param o 实体
* @return
*/
public static String[] getFiledName(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i].getType());
fieldNames[i] = fields[i].getName();
}
return fieldNames;
} /**
* 获取属性类型(type),属性名(name),属性值(value)的map组成的list
*
* @param o 实体
* @return
*/
public static List<Map<String, Object>> getFiledsInfo(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
// String[] fieldNames = new String[fields.length];
List<Map<String, Object>> list = new ArrayList<>();
Map<String, Object> infoMap = null;
for (int i = 0; i < fields.length; i++) {
infoMap = new HashMap<String, Object>();
infoMap.put("type", fields[i].getType().toString());
infoMap.put("name", fields[i].getName());
infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
list.add(infoMap);
}
return list;
} /**
* 获取对象的所有属性值,返回一个对象数组
*
* @param o 实体
* @return
*/
public static Object[] getFiledValues(Object o) {
String[] fieldNames = getFiledName(o);
Object[] value = new Object[fieldNames.length];
for (int i = 0; i < fieldNames.length; i++) {
value[i] = getFieldValueByName(fieldNames[i], o);
}
return value;
} /**
* 根据对象属性名设置属性值
*
* @param fieldName 字段名
* @param value 字段值
* @param o 实体
* @return
*/
public static void setFieldValueByName(String fieldName, Object o,Object value) {
try {
BeanInfo obj =Introspector.getBeanInfo(o.getClass(), Object.class);
PropertyDescriptor[] pds = obj.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if(pd.getName().equals(fieldName)){
pd.getWriteMethod().invoke(o, value);
break;
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
测试用例如下:
/**
* 根据实体和属性名获取值
*/
@Test
public void testGetField(){
TruckBills truckBills = iTruckBillsService.geTruckBills("02cb5069b44f45dca578e5ada08bf513", "88"); String orderSn = (String) ObjectFieldUtil.getFieldValueByName("orderSn", truckBills);
String shipper = (String) ObjectFieldUtil.getFieldValueByName("shipper", truckBills); String[] fieldNames = ObjectFieldUtil.getFiledName(truckBills); List<Map<String, Object>> listMap = ObjectFieldUtil.getFiledsInfo(truckBills); System.out.println("---------------------------");
System.out.println(orderSn);
System.out.println(shipper);
System.out.println(Arrays.toString(fieldNames));
for (Map<String, Object> map : listMap) {
System.out.println("---------------------------");
Set<Entry<String, Object>> entrySet = map.entrySet();
for (Entry<String, Object> entry : entrySet) {
System.out.println(entry.getKey() + "-----" + entry.getValue());
}
System.out.println("---------------------------");
}
}
还有一种将字符串转换成java代码并执行的方法:Java Expression Language (JEXL) 是一个表达式语言引擎,可以用来在应用或者框架中使用。
JEXL受Velocity和JSP 标签库 1.1 (JSTL) 的影响而产生的,需要注意的是,JEXL 并不时 JSTL 中的表达式语言的实现。
需要先添加jar包,maven配置如下:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
<version>2.0</version>
</dependency>
核心代码如下:
public class DyMethodUtil { /**
* 将字符串转换成java代码并执行
*
* @param jexlExp 需要转换的字符串
* @param map 参数集合
* @return 方法执行结果
* 如:
* String jexlExp="testService.save(person)";
* map.put("testService",testService);
* map.put("person",person);
*/
public static Object invokeMethod(String jexlExp, Map<String, Object> map) {
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression(jexlExp);
JexlContext jc = new MapContext();
for (String key : map.keySet()) {
jc.set(key, map.get(key));
}
if (null == e.evaluate(jc)) {
return "";
}
return e.evaluate(jc);
}
}
测试示例如下:
/**
* 动态构建
*/
@Test
@Rollback(false)
public void testTemple(){
//1.拿到结果集
//2.构建语言表达式
//3.动态构建 TruckBills truckBills = iTruckBillsService.geTruckBills("02cb5069b44f45dca578e5ada08bf513", "88"); List<TruckGoodsAddr> truckGoodsAddrs = truckBills.getTruckGoodsAddrs();
TruckOther truckOther = truckBills.getTruckOther(); Map<String, Object> map = new HashMap<>();
map.put("truckBills", truckBills); System.out.println("------------------------");
System.out.println(JsonBinder.buildNormalBinder().toJson(map));
System.out.println("------------------------"); String expression = "truckBills.getTruckGoodsAddrs().get(0).getBillsId()"; Object aa = DyMethodUtil.invokeMethod(expression, map);
System.out.println("------------------------");
System.out.println(JsonBinder.buildNormalBinder().toJson(aa));
System.out.println("------------------------");
}
获取对象属性类型、属性名称、属性值的研究:反射和JEXL解析引擎的更多相关文章
- js中如何获取对象的长度和名称
js如何获取对象长度和名称 一.总结 一句话总结:对象的长度不能用.length获取,用js原生的Object.keys可以获取到 var obj = {'name' : 'Tom' , 'sex' ...
- typescript 关于class属性类型定义被属性默认值覆盖的问题及解决方式
问题来源于 React.component的第二个参数的类型定义问题,我构建了以下简化demo,方便描述问题: class P<STATE> { public state: STATE; ...
- C#中通过反射方法获取控件类型和名称
这个方法是简单的也是神奇的. 有木有想过,将自己项目中的所有类型,包括自定义类型的命名空间和名称全部获取出来? 有木有想过,有一种简便的方法可以自动化管理项目中的控件和窗体? 有木有想过... 首先, ...
- 获取httpservletrequest所有参数的名称和值
1.方法 private Map showParams(HttpServletRequest request) { Map map = new HashMap(); Enumeration param ...
- 精确获取对象的类型:Object.prototype.toString()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
- C#获取EF实体对象或自定义属性类的字段名称和值
在年前上班的时候遇到了一个问题是这样描述的:我前台设计一个页面,是标签和文本框,当用户修改了哪个文本框的值,将该修改前的值.修改后的值,该值对应的字段,该值对应的行id获取到保存到数据库的某张表里.现 ...
- 【java】java获取对象属性类型、属性名称、属性值
java获取对象属性类型.属性名称.属性值 获取属性 修饰符:[在Field[]循环中使用] String modifier = Modifier.toString(fields[i].getModi ...
- java获取对象属性类型、属性名称、属性值
/** * 根据属性名获取属性值 * */ private Object getFieldValueByName(String fieldName, Object o) { try { String ...
- java获取对象属性类型、属性名称、属性值 【转】
/** * 根据属性名获取属性值 * */ private Object getFieldValueByName(String fieldName, Object o) { try { String ...
随机推荐
- 微信小程序左右滑动切换图片酷炫效果
开门见山,先上效果吧!感觉可以的用的上的再往下看. 心动吗?那就继续往下看! 先上页面结构吧,也就是wxml文件,其实可以理解成微信自己封装过的html,这个不多说了,不懂也没必要往下看了. < ...
- spring使用c3p0报错
java.sql.SQLException: Connections could not be acquired from the underlying database! at com.mchang ...
- 解决 PHPExcel 长数字串显示为科学计数[转]
解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...
- python_协程方式操作数据库
# !/usr/bin/python3 # -*- coding: utf-8 -*- import requests import gevent import pymysql from gevent ...
- libev-4.20编译安装及简单使用
1.源码下载地址: http://www.csdn.net/tag/libev/download 2.库的编译与安装 解压文件,进入文件目录 编译的时候需要首先切换为管理员(root)账户,然后执行以 ...
- 监控 Linux 性能的 18 个命令行工具[转]
对于系统和网络管理员来说每天监控和调试Linux系统的性能问题是一项繁重的工作.在IT领域作为一名Linux系统的管理员工作5年后,我逐渐认识到监控和保持系统启动并运行是多么的不容易.基于此原因,我们 ...
- 9 C. Hexadecimal's Numbers
题目链接 http://codeforces.com/contest/9/problem/C 题目大意 输入n,计算出n之内只有0和1组成的数字的数量 分析 k从1开始,只要小于n,就给sum++,并 ...
- Android图像数据传递到C++的一些坑
最近在做一个Android图象识别的app, 通过相机预览或者是拍照功能获取图像数据,然后将图像数据传递到本地C++的图像识别so库.在这个过程中花的时间最多的就是数据传输问题.谨以此坑,警示未来! ...
- JSP自定义标签就是如此简单
tags: JSP 为什么要用到简单标签? 上一篇博客中我已经讲解了传统标签,想要开发自定义标签,大多数情况下都要重写doStartTag(),doAfterBody()和doEndTag()方法,并 ...
- [DeeplearningAI笔记]02_3.1-3.2超参数搜索技巧与对数标尺
Hyperparameter search 超参数搜索 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.1 调试处理 需要调节的参数 级别一:\(\alpha\)学习率是最重要的需要调节的 ...