/*
*MIT License
*
*Copyright (c) 2019 chenshuai cs4380@163.com
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package com.cs.cslc.common.util;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import java.lang.reflect.*;
/**
* ReflectionUtils .
* 反射工具类.
* 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
*
* @author cs4380 https://gitee.com/xhbug_cs4380 cs4380@163.com
* @version 1.0
* @since 2019-10-02 11:50
*/
@SuppressWarnings("rawtypes")
public class ReflectionUtils {
private static final String SETTER_PREFIX = "set";
private static final String GETTER_PREFIX = "get";
private static final String CGLIB_CLASS_SEPARATOR = "$$";
private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
public static Object invokeGetter(Object obj, String propertyName) {
Object object = obj;
for (String name : StringUtils.split(propertyName, ".")) {
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
object = invokeMethod(object, getterMethodName, new Class[]{}, new Object[]{});
}
return object;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public static void invokeSetter(Object obj, String propertyName, Object value) {
Object object = obj;
String[] names = StringUtils.split(propertyName, ".");
for (int i = 0; i < names.length; i++) {
if (i < names.length - 1) {
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
object = invokeMethod(object, getterMethodName, new Class[]{}, new Object[]{});
} else {
String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
invokeMethodByName(object, setterMethodName, new Object[]{value});
}
}
}
/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
public static Object getFieldValue(final Object obj, final String fieldName) {
Field field = getAccessibleField(obj, fieldName);
if (field == null) {
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
}
Object result = null;
try {
result = field.get(obj);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常{}", e.getMessage());
}
return result;
}
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public static void setFieldValue(final Object obj, final String fieldName, final Object value) {
Field field = getAccessibleField(obj, fieldName);
if (field == null) {
logger.error("Could not find field [" + fieldName + "] on target [" + obj + "]");
return;
}
try {
field.set(obj, convert(value, field.getType()));
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常:{}", e.getMessage());
}
}
public static Object convert(Object object, Class<?> type) {
if (object instanceof Number) {
Number number = (Number) object;
if (type.equals(byte.class) || type.equals(Byte.class)) {
return number.byteValue();
}
if (type.equals(short.class) || type.equals(Short.class)) {
return number.shortValue();
}
if (type.equals(int.class) || type.equals(Integer.class)) {
return number.intValue();
}
if (type.equals(long.class) || type.equals(Long.class)) {
return number.longValue();
}
if (type.equals(float.class) || type.equals(Float.class)) {
return number.floatValue();
}
if (type.equals(double.class) || type.equals(Double.class)) {
return number.doubleValue();
}
}
if (type.equals(String.class)) {
return object == null ? "" : object.toString();
}
return object;
}
/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
*/
public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
final Object[] args) {
Method method = getAccessibleMethod(obj, methodName, parameterTypes);
if (method == null) {
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
}
try {
return method.invoke(obj, args);
} catch (Exception e) {
throw convertReflectionExceptionToUnchecked(e);
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符,
* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
*/
public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
Method method = getAccessibleMethodByName(obj, methodName);
if (method == null) {
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
}
try {
return method.invoke(obj, args);
} catch (Exception e) {
e.printStackTrace();
throw convertReflectionExceptionToUnchecked(e);
}
}
/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
* <p>
* 如向上转型到Object仍无法找到, 返回null.
*/
public static Field getAccessibleField(final Object obj, final String fieldName) {
Validate.notNull(obj, "object can't be null");
Validate.notBlank(fieldName, "fieldName can't be blank");
for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
xyq2024
- 粉丝: 2962
- 资源: 5572
最新资源
- 基于vue的订餐小程序springboot-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于ssm选课系统+ssm-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于Vue.js的校园防疫微信小程序开发+ssm-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于微信微服务架构的汽车租赁系统的设计与实现_zaxzu-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于uniapp+springboot的校园失物招领系统的设计与实现--论文pf-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- Python 实现 BO-KNN(贝叶斯优化 K 近邻算法)进行分类预测的示例(含完整的程序,GUI设计和代码详解)
- 基于微信的高校教务管理系统设计与实现springboot-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于vue和微信小程序的校园自助打印系统+springboot-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- SSA-RF和RF麻雀算法优化随机森林多特征分类预测(Matlab) 1.运行环境Matlab2018b及以上; 2.麻雀算法优化随机森林树木棵树和森林深度,输入12个特征,分四类,可视化展示分类准确
- 基于微信小程序的仓储管理系统_r275i--论文-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于微信的乐室预约小程序+ssm-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于微信小程序的超市购物系统代码--论文pf-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于微信小程序的付费自习室管理系统-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于微信小程序的短文写作竞赛管理系统_r653y--论文-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.zip
- 基于微信的追星小程序+ssm-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
- 基于微信的设备故障报修管理系统设计与实现+ssm-微信小程序毕业项目,适合计算机毕-设、实训项目、大作业学习.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈