com.centit.support.algorithm.ReflectionOpt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of centit-utils Show documentation
Show all versions of centit-utils Show documentation
java 常用工具类,作为 apache-commons的补充
package com.centit.support.algorithm;
import com.centit.support.file.FileType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 提供一些反射方面缺失功能的封装.
* @author codefan
*/
@SuppressWarnings("unused")
public abstract class ReflectionOpt {
private ReflectionOpt() {
throw new IllegalAccessError("Utility class");
}
protected static final Logger logger = LoggerFactory.getLogger(ReflectionOpt.class);
/*
* 循环向上转型,获取对象的DeclaredField.
*
* @throws NoSuchFieldException 如果没有该Field时抛出.
*/
public static Field getDeclaredField(Object object, String propertyName) throws NoSuchFieldException {
assert(object != null);
assert(propertyName != null && !propertyName.isEmpty());
return getDeclaredField(object.getClass(), propertyName);
}
/*
* 循环向上转型,获取对象的DeclaredField.
*
* @throws NoSuchFieldException 如果没有该Field时抛出.
*/
public static Field getDeclaredField(Class> clazz, String propertyName) throws NoSuchFieldException {
assert(clazz != null);
assert(propertyName != null && !propertyName.isEmpty());
//Assert.notNull(object);
//Assert.hasText(propertyName);
for (Class> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
Field f = superClass.getDeclaredField(propertyName);
if(f!=null)
return f;
} catch (NoSuchFieldException e) {
logger.debug(e.getMessage());
// Field不在当前类定义,继续向上转型
}
}
throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + propertyName);
}
/*
* 获得对象的属性值
* @param object
* @param field
* @return
* @throws NoSuchFieldException
*/
public static Object forceGetFieldValue(Object object,Field field ) {
assert(object != null);
boolean accessible = field.isAccessible();
field.setAccessible(true);
Object result = null;
try {
result = field.get(object);
} catch (IllegalAccessException e) {
logger.info("error wont' happen."+ e.getMessage());
}
field.setAccessible(accessible);
return result;
}
/*
* 获得get field value by getter
*/
public static Object getFieldValue(Object obj, String fieldName) {
Method md=null;
try {
md = obj.getClass().getMethod("get" + StringUtils.capitalize(fieldName));
}catch (NoSuchMethodException noGet ){
try {
md = obj.getClass().getMethod("is" + StringUtils.capitalize(fieldName));
}catch (Exception e ){
logger.error(noGet.getMessage() + e.getMessage());
}
}catch (Exception e) {
logger.error(e.getMessage());
}
if(md==null){
try{
return forceGetProperty(obj, fieldName);
}catch (Exception e) {
logger.error(e.getMessage());
}
}else{
try{
return md.invoke(obj);
} catch (Exception e) {
logger.error(e.getMessage());
}
}
return null;
}
public static boolean setFieldValue(Object object, String fieldName, Object newValue, Class> paramType) {
Class> relParamType = (paramType!=null)?paramType:(newValue!=null?newValue.getClass():null);
boolean hasSetValue=false;
if(relParamType != null) {
try {
Method md = object.getClass().getMethod("set" + StringUtils.capitalize(fieldName), relParamType);
md.invoke(object, newValue);
hasSetValue = true;
} catch (NoSuchMethodException noSet) {
logger.error(noSet.getMessage(), noSet);
} catch (Exception e) {
logger.error(e.getMessage());
}
}
if(!hasSetValue){
try{
forceSetProperty(object, fieldName, newValue);
hasSetValue = true;
}catch (Exception e) {
logger.error(e.getMessage());
}
}
return hasSetValue;
}
public static boolean setFieldValue(Object object, String fieldName, Object newValue) {
return setFieldValue(object, fieldName, newValue, null);
}
/*
* 获得get field value by getter
*/
public static Object getFieldValue(Object obj, Field field) {
try {
return field.get(obj);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
/*
* 获取对象变量值,忽略private,protected修饰符的限制.
*
* @throws NoSuchFieldException 如果没有该Field时抛出.
*/
public static Object forceGetProperty(Object object, String propertyName) throws NoSuchFieldException {
assert(object != null);
assert(propertyName != null && !propertyName.isEmpty());
Field field = getDeclaredField(object, propertyName);
/* if(field==null){
log.debug("property not found. (没有找到对应的属性) 对象:" + object.toString() +" 属性 :"+ propertyName);
return null;
}*/
return forceGetFieldValue(object,field);
}
/*
* 设置对象变量值,忽略private,protected修饰符的限制.
*
* @throws NoSuchFieldException 如果没有该Field时抛出.
*/
public static void forceSetProperty(Object object, String propertyName, Object newValue)
throws NoSuchFieldException {
assert(object != null);
assert(propertyName != null && !propertyName.isEmpty());
Field field = getDeclaredField(object, propertyName);
/* if(field==null){
log.debug("property not found. (没有找到对应的属性) 对象:" + object.toString() +" 属性 :"+ propertyName);
return;
}*/
boolean accessible = field.isAccessible();
if(!accessible) {
field.setAccessible(true);
}
try {
field.set(object, newValue);
} catch (IllegalAccessException e) {
logger.error("Error won't happen."+e.getMessage(), e);
}
if(!accessible) {
field.setAccessible(accessible);
}
}
/*
* 调用对象函数,忽略private,protected修饰符的限制.
*
* @throws NoSuchMethodException 如果没有该Method时抛出.
*/
public static Object invokePrivateMethod(Object object, String methodName, Object... params)
throws NoSuchMethodException {
assert(object != null);
assert(methodName != null && !methodName.isEmpty());
Class>[] types = new Class[params.length];
for (int i = 0; i < params.length; i++) {
types[i] = params[i].getClass();
}
Class> clazz = object.getClass();
Method method = null;
for (Class> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
method = superClass.getDeclaredMethod(methodName, types);
break;
} catch (NoSuchMethodException e) {
logger.debug("方法不在当前类定义,继续向上转型");
// 方法不在当前类定义,继续向上转型
}
}
if (method == null)
throw new NoSuchMethodException("No Such Method:" + clazz.getSimpleName() + methodName);
boolean accessible = method.isAccessible();
method.setAccessible(true);
Object result = null;
try {
result = method.invoke(object, params);
} catch (Exception e) {
//ReflectionUtils.handleReflectionException(e);
logger.error(e.getMessage() );
logger.error(e.getMessage(),e);//e.printStackTrace();
}
method.setAccessible(accessible);
return result;
}
/*
* 取得Field列表.
*/
public static Field[] getFields(Object object) {
return object.getClass().getDeclaredFields();
}
/*
* 按Filed的类型取得Field列表.
*/
public static List getFieldsByType(Object object, Class> type) {
List list = new ArrayList<>();
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
if (type.isAssignableFrom(field.getType())) {
list.add(field);
}
}
return list;
}
/*
* 按FiledName获得Field的类型.
*/
public static Class> getPropertyType(Class> type, String name) throws NoSuchFieldException {
return getDeclaredField(type, name).getType();
}
/*
* 获得field的getter函数名称.
*/
public static String methodNameToField(String methodName) {
if(methodName== null)
return null;
int sl = methodName.length();
if( sl > 3 && (methodName.startsWith("get") || methodName.startsWith("set") ))
return methodName.substring(3,4).toLowerCase() + methodName.substring(4);
if( sl > 2 && methodName.startsWith("is"))
return methodName.substring(2,3).toLowerCase() + methodName.substring(3);
return methodName;
}
/*
* 获得field的getter函数,如果找不到该方法,返回null.
*/
public static Method getGetterMethod(Class> classType, Class> propertyType, String fieldName) {
try {
String getFuncName = (boolean.class.equals(propertyType) || Boolean.class.isAssignableFrom(propertyType))?
"is" + StringUtils.capitalize(fieldName) : "get" + StringUtils.capitalize(fieldName);
Method md = classType.getMethod(getFuncName);
if(propertyType.isAssignableFrom( md.getReturnType()))
return md;
else
return null;
} catch (NoSuchMethodException e) {
logger.error(e.getMessage());
return null;
}
}
/*
* 获得field的getter函数,如果找不到该方法,返回null.
*/
public static Method getGetterMethod(Class> classType, String fieldName) {
try {
Method md = classType.getMethod("get" + StringUtils.capitalize(fieldName));
if(void.class.equals(md.getReturnType()))
return null;
else
return md;
} catch (NoSuchMethodException e) {
logger.error(e.getMessage());
return null;
}
}
/*
* 获得field的getter函数,如果找不到该方法,返回null.
*/
public static Method getSetterMethod(Class> classType, Class> propertyType, String fieldName) {
try {
return classType.getMethod("set" + StringUtils.capitalize(fieldName), propertyType);
} catch (NoSuchMethodException e) {
logger.error(e.getMessage());
return null;
}
}
/*
* 获得 对象的 属性
* @param sourceObj
* @param expression
* @return
*/
public static Object attainExpressionValue(Object sourceObj , String expression){
if(sourceObj==null || StringUtils.isBlank(expression))
return null;
if(".".equals(expression))
return sourceObj;
int nPos = expression.indexOf('.');
String fieldValue;
String restExpression=".";
if(nPos>0){
fieldValue = expression.substring(0,nPos).trim();
if(expression.length()>nPos+1)
restExpression = expression.substring(nPos+1);
}else
fieldValue = expression.trim();
int nAarrayInd = -1;
nPos = fieldValue.indexOf('[');
if(nPos>0){
String sArrayInd = fieldValue.substring(nPos+1,fieldValue.length()-1);
if(StringRegularOpt.isNumber(sArrayInd))
nAarrayInd = Double.valueOf(sArrayInd).intValue();
fieldValue = fieldValue.substring(0,nPos);
}
Object retObj;
if(sourceObj instanceof Map ){
@SuppressWarnings("unchecked")
Map objMap = (Map) sourceObj;
retObj = objMap.get(fieldValue);
}else{
//如果是一个标量则不应该再有属性,所以统一返回null
if(ReflectionOpt.isScalarType(sourceObj.getClass())){
return null;
}else
retObj = ReflectionOpt.getFieldValue(sourceObj,fieldValue);
}
if(retObj==null)
return null;
if(retObj instanceof Collection){
Collection> objlist = (Collection>) retObj;
int objSize = objlist.size();
if(objSize<1)
return null;
if(nAarrayInd>=0){
if( nAarrayInd =0){
if(nAarrayInd classType, String fieldName) {
try {
return classType.getMethod("is" + StringUtils.capitalize(fieldName));
} catch (NoSuchMethodException e) {
logger.error(e.getMessage(), e);
}
return null;
}
/*
* 获取所有getMethod方法
*/
public static List getAllGetterMethod(Class> type) {
try {
Method[] mths = type.getMethods();
List getMths = new ArrayList();
for (Method mth : mths)
if( ( mth.getName().startsWith("get") || mth.getName().startsWith("is") )
&& ! mth.getName().equals("getClass")
&& ! void.class.equals(mth.getReturnType())
//&& ! mth.getReturnType().getName().equals("void")
&& mth.getGenericParameterTypes().length < 1 )
getMths.add(mth);
return getMths;
} catch (SecurityException e) {
logger.error(e.getMessage(), e);
}
return null;
}
/*
* 获取所有setMethod方法
*/
public static List getAllSetterMethod(Class> type) {
try {
Method[] mths = type.getMethods();
List setMths = new ArrayList();
for (Method mth : mths) {
String methodName = mth.getName();
if( methodName.startsWith("set")
&& methodName.length()>=4
//&& mth.getReturnType().getName().equals("void")
&& mth.getGenericParameterTypes().length == 1 ) {
setMths.add(mth);
}
}
return setMths;
} catch (SecurityException e) {
logger.error(e.getMessage(), e);
}
return null;
}
/*
* 调用对象的无参数函数
*/
public static void invokeNoParamFunc(Object demander,String smethod) {
try {
//"copyNotNullProperty"
Method setV = demander.getClass().getMethod(smethod);
//Class rt = d.getReturnType();
/* if(setV == null)
return; */
setV.invoke(demander);
} catch (NoSuchMethodException | SecurityException
| IllegalAccessException | InvocationTargetException e) {
logger.error(e.getMessage(), e);
}
}
/*
* 调用相同类型的类之间的二元操作
*/
public static void invokeBinaryOpt(T demander,String smethod,T param) {
try {
//"copyNotNullProperty"
Method setV = demander.getClass().getMethod(smethod ,demander.getClass());
//Class rt = d.getReturnType();
/* if(setV == null)
return; */
setV.invoke(demander,param);
} catch (NoSuchMethodException | SecurityException | IllegalArgumentException
| IllegalAccessException | InvocationTargetException e) {
logger.error(e.getMessage(), e);
}
}
/**
* @param clazz The class to introspect
* @return the first generic declaration, or Object.class
if cannot be determined
*/
public static Class> getSuperClassGenricType(Class> clazz) {
return getSuperClassGenricType(clazz, 0);
}
/**
* @param clazz
* clazz The class to introspect
* @param index
* the Index of the generic declaration,start from 0.
* @return the index generic declaration, or Object.class
if
* cannot be determined
*/
public static Class> getSuperClassGenricType(Class> clazz, int index) {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+ params.length);
return Object.class;
}
if (!(params[index] instanceof Class)) {
logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
return Object.class;
}
return (Class>) params[index];
}
/** isPrimitiveType
* 判断一个类型是否是基础类型 int boolean void float double char
* 或者单值类型 String Date Integer Float Double, scalar
* @param tp isPrimitiveType
* @return isPrimitiveType
*/
public static boolean isPrimitiveType(Class> tp){
return tp.isPrimitive() || tp.getName().startsWith("java.lang.");
}
/** isScalarType
* 判断一个类型是否是基础类型 int boolean void float double char
* 或者单值类型 String Date Integer Float Double, scalar
* @param tp isScalarType
* @return isScalarType
*/
public static boolean isScalarType(Class> tp){
if(tp.isPrimitive())
return true;
String tpName = tp.getName();
if(tpName.startsWith("java.lang."))
return true;
if(tpName.startsWith("java.sql."))
return true;
if( java.util.Date.class.isAssignableFrom(tp))// "java.util.Date".equals(tp.getName()))
return true;
if( java.util.UUID.class.isAssignableFrom(tp))// "java.util.UUID".equals(tp.getName()))
return true;
return false;
}
public static boolean isNumberType(Class> tp){
return java.lang.Number.class.isAssignableFrom(tp);
//tp.getSuperclass().equals(Number.class) || tp.equals(Number.class);
}
/**
* 判断一个对象是否是 数组[]、Collection(List)
* @param obj 对象
* @return 否是 数组[]
*/
public static boolean isArray(Object obj){
Class> tp = obj.getClass();
if(tp.isArray())
return true;
//if(obj instanceof Object[])
// return true;
if(obj instanceof Collection>)
return true;
return false;
}
/**
* 判断一个类型是否是 数组[]、Collection(List)
* @param tp 类型
* @return 否是 数组[]
*/
public static boolean isArrayType(Class> tp){
if(tp.isArray())
return true;
if(Collection.class.isAssignableFrom(tp))
return true;
return false;
}
/*
* 得到当前方法的名字
*/
public static String getCurrentMethodName(){
return Thread.currentThread().getStackTrace()[1].getMethodName();
}
/*
* 类 clazz 必需有一个无参数的默认构造函数
* 这个Map需要和属性严格匹配,如果需要更灵活的匹配可以 使用OBNL
* 或者转换为JSONString在用JSON转化为对象
* @param clazz
* @param properties
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public T createObjectFromMap( Class clazz, Map properties)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException{
T obj = (T) clazz.newInstance();
try {
Method[] mths = clazz.getMethods();
for (Method mth : mths){
Type[] paramTypes = mth.getGenericParameterTypes();
String methodName = mth.getName();
if( methodName.startsWith("set")
&& methodName.length()>=4
&& paramTypes.length == 1 ){
Object value = properties.get(methodName.substring(3,4).toLowerCase() + methodName.substring(4));
if(value!=null){
mth.invoke(obj,value);
}
}
}
} catch (SecurityException e) {
logger.error(e.getMessage(), e);
}
return obj;
}
public static String getJavaTypeName(Class> type) {
String typeName = type.getTypeName();
if(typeName.indexOf('.')<1) {
return typeName;
} else if(typeName.startsWith("java.lang.")
|| "java.util.Date".equals(typeName)
|| "java.sql.Clob".equals(typeName)
|| "java.sql.Blob".equals(typeName)
|| "java.util.UUID".equals(typeName)
|| "java.math.BigDecimal".equals(typeName)
|| "java.math.BigInteger".equals(typeName)) {
return FileType.getFileExtName(typeName);
} else if(typeName.startsWith("java.sql.")) {
return "sql" + FileType.getFileExtName(typeName);
} else {
return typeName;
}
}
}