java对象通过点运算符操作对象属性的方式没法使用for,while等循环,此工具主要解决这一问题.
例如:有一对象包含属性有一定规律
obj1: { name1: "张三" , age1: 1, name2: "李四" , age2: 2, .... } |
要将此对象拆为多个小对象
objList:[ { name: "张三" , age: 1 }, { name: "李四" , age: 2 } ] |
为了应对这种不能使用循环获取属性的情况,编写了此工具类
核心实现代码如下:
/** * @param o * 操作对象 * @param methodName * 方法名 * @param attName * 属性名 * @param value * 值 * @return get方法返回实际值 set方法返回操作后对象 */ private static Object Operation(Object o, String methodName, String attName, Class<?> paramType, Object value) { // 方法赋值出错标志 boolean opErr = false ; Object res = null ; Class<?> type = o.getClass(); try { Method method = null ; if (methodName.indexOf( "get" ) != - 1 ) { // get方法<br> // 获取方法 method = type.getMethod(methodName);<br> // 执行 res = method.invoke(o); } else { // set方法<br> // 当没有传入参数类型时通过value获取参数类型 paramType = paramType == null ? value.getClass() : paramType;<br> // 获取方法 method = type.getMethod(methodName, paramType);<br> // 执行 method.invoke(o, value); res = o; } } catch (Exception e) {<br> // 通过get/set方法操作属性失败 opErr = true ; if (SHOW_LOG) { System.err.println(getThisName() + ": [WARN] 直接对属性'" + attName + "进行操作(不借助get/set方法)." ); } } if (opErr) {<br> // 通过打破封装方式直接对值进行操作 try { Field field = null ;<br> // 获取属性 field = type.getDeclaredField(attName);<br> // 打破封装 field.setAccessible( true ); if (methodName.indexOf( "get" ) != - 1 ) {<br> // get方法<br> // 获取属性值 res = field.get(o); } else {<br> // set方法 <br> // 设置属性值 field.set(o, value); res = o; } } catch (Exception e) { //两种方法都操作失败 if (SHOW_LOG) { System.err.println(getThisName() + ": [ERROR] 属性'" + attName + "'操作失败." ); } } } return res; } |
set方法如下:
/** * 设置属性值 * * @param o * 操作对象 * @param attName * 属性名 * @param value * 参数值 * @param paramType * 参数类型 * @return 操作后对象 */ @SuppressWarnings ( "unchecked" ) public static <T> T set(T o, String attName, Object value, Class<?> paramType) { if (o == null || attName == null || attName.isEmpty()) { return null ; } String methodName = attNameHandle( "set" , attName); return (T) Operation(o, methodName, attName, paramType, value); } |
get方法如下:
/** * 获取属性值 * * @param o * 操作对象 * @param attName * 属性名 * @param returnType * 返回值类型 * @return */ @SuppressWarnings ( "unchecked" ) public static <T> T get(Object o, String attName, Class<T> returnType) { if (o == null || attName == null || attName.isEmpty()) { return null ; } String methodName = attNameHandle( "get" , attName); return (T) Operation(o, methodName, attName, null , null ); } |
通过属性名获取get/set方法名:
/** * 属性名处理 * * @param method * 方法(get/set) * @param attName * @return */ private static String attNameHandle(String method, String attName) { StringBuffer res = new StringBuffer(method); <br> // 属性只有一个字母 if (attName.length() == 1 ) { res.append(attName.toUpperCase()); } else {<br> // 属性包含两个字母及以上 char [] charArray = attName.toCharArray(); // 当前两个字符为小写时,将首字母转换为大写 if (Character.isLowerCase(charArray[ 0 ]) && Character.isLowerCase(charArray[ 1 ])) { res.append(Character.toUpperCase(charArray[ 0 ])); res.append(attName.substring( 1 )); } else { res.append(attName); } } return res.toString(); } |
完整代码:https://github.com/GFuZan/reflexTools
原文出处:https://www.cnblogs.com/gfuzan/p/9614488.html