java反射工具类--通过指定属性名,获取/设置对象属性值

Posted gfuzan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java反射工具类--通过指定属性名,获取/设置对象属性值相关的知识,希望对你有一定的参考价值。

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方法
        // 获取方法
				method = type.getMethod(methodName);
        // 执行
				res = method.invoke(o);
			} else {
				// set方法
        // 当没有传入参数类型时通过value获取参数类型
				paramType = paramType == null ? value.getClass() : paramType;
        // 获取方法
				method = type.getMethod(methodName, paramType);
        // 执行
				method.invoke(o, value);
				res = o;
			}
		} catch (Exception e) {
      // 通过get/set方法操作属性失败
			opErr = true;
			if (SHOW_LOG) {
				System.err.println(getThisName() + ": [WARN] 直接对属性‘" + attName + "进行操作(不借助get/set方法).");
			}
		}

		if (opErr) {
      // 通过打破封装方式直接对值进行操作
			try {
				Field field = null;
        // 获取属性
				field = type.getDeclaredField(attName);
        // 打破封装
				field.setAccessible(true);

				if (methodName.indexOf("get") != -1) {
        // get方法
        // 获取属性值
					res = field.get(o);
				} else {
        // set方法 
        // 设置属性值
					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);
		// 属性只有一个字母
        if (attName.length() == 1) {
            res.append(attName.toUpperCase());
        } else {
		// 属性包含两个字母及以上
            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

以上是关于java反射工具类--通过指定属性名,获取/设置对象属性值的主要内容,如果未能解决你的问题,请参考以下文章

java 27 - 8 反射之 通过反射来设置某个对象的某个属性为指定值

java如何通过反射获取包中所有的类?

java 通过反射获取调用类方法及属性

java 通过反射获取调用类方法及属性

C#通过反射获取不同命名空间下的类(属性和方法)

C++遍历获得一个类的所有属性名,对该类的实例的所有属性的值 ...~~