Java反射机制

一、案例

1. 运行时利用带参构造方法生成类实例

利用Constructor的newInstance()方法,首先准备一个Class[]数组作为Constructor的参数类型,然后调用Class对象的getConstructor()方法获得一个专属的Constructor对象,最后再准备一个Object[]作为Constructor对象newInstance()方法的实参

// 利用反射构造带参数的类的实例
// 得到类实例
Class clazz = Class.forName(User.class.getName());
Class[] paramType = new Class[] { String.class, int.class, String.class };
// 得到构造方法
Constructor constructor = clazz.getConstructor(paramType);
// 实例构造方法的参数数组
Object[] params = new Object[] { "Paulz", 29, "111111" };
// 利用带参构造方法实例类
Object obj = constructor.newInstance(params);
System.out.println(((User) obj).getUserName());// 结果:Paulz


2. cope一个对象,封装各个属性值

public static Object copy(Object obj) throws Exception {
	// 获得对象的类型
	Class clazz = obj.getClass();
	System.out.println("该对象的类型是 = " + clazz.getName());
	// 通过默认构造方法创建一个新的对象,视其参数动态决定调用哪个构造函数
	Object objectCopy = clazz.getConstructor(new Class[] {}).newInstance(new Object[] {});
	// 获得对象的所有属性,包括私有属性
	Field[] fields = clazz.getDeclaredFields();
	for (int i = 0; i < fields.length; i++) {
		Field field = fields[i];

		// 获得数组中对应的属性名称
		String fieldName = field.getName();

		// 获得相应属性的getter和setter方法名称
		String letter = fieldName.substring(0, 1).toUpperCase();
		String getName = "get" + letter + fieldName.substring(1);
		String setName = "set" + letter + fieldName.substring(1);

		// 获得相应的getter和setter方法
		Method getMethod = clazz.getMethod(getName, new Class[] {});
		Method setMethod = clazz.getMethod(setName, new Class[] { field.getType() });

		// 调用源对象的getter方法
		Object value = getMethod.invoke(obj, new Object[] {});
		System.out.println("value = " + value);

		// 调用copy的setter方法,将源对象值赋给新对象对应的方法
		setMethod.invoke(objectCopy, new Object[] { value });
	}
	return objectCopy;
}


二、实现例子

ReflectUtils代码:

package reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

public class ReflectUtils {
	/**
	 * 利用带参构造方法生成类实例
	 * 
	 * @param map
	 *            参数
	 * @param clazz
	 *            返回类类型
	 * @return
	 * @throws Exception
	 * @throws
	 */
	public static <T> T getObject(Map<String, Object> map, Class<T> clazz) throws Exception {
		if (map == null) {
			return null;
		}
		Constructor<T> constructor = clazz.getConstructor(Map.class);
		T obj = constructor.newInstance(map);
		return obj;
	}

	/**
	 * 拷贝一个新对象
	 * 
	 * @param obj
	 *            对象
	 * @param clazz
	 *            对象类型
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static <T> T copy(T obj) throws Exception {
		// 获得对象的类型
		Class<T> clazz = (Class<T>) obj.getClass();
		// 通过默认构造方法创建一个新的对象
		T objCopy = clazz.newInstance();
		// 获得对象的所有属性,包括私有属性
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			// 获得属性名称
			String fieldName = field.getName();

			// 获得相应的属性的getter和setter方法名称
			String letter = fieldName.substring(0, 1).toUpperCase();
			String getName = "get" + letter + fieldName.substring(1);
			String setName = "set" + letter + fieldName.substring(1);
			Method getMethod = clazz.getMethod(getName, new Class[] {});
			Method setMethod = clazz.getMethod(setName, new Class[] { field.getType() });

			// 调用源对象的getter方法
			Object value = getMethod.invoke(obj, new Object[] {});

			// 调用copy的setter方法,将源对象值赋给新对象对应的方法
			setMethod.invoke(objCopy, new Object[] { value });
		}
		return objCopy;
	}
}


User代码:

package reflect;

import java.util.Map;

public class User {

	private String userName;// 姓名
	private Integer age;// 年龄
	public String password;// 密码

	public User() {
	}

	/**
	 * 带参数的构造函数
	 * 
	 * @param userName
	 *            姓名
	 * @param age
	 *            年龄
	 * @param password
	 *            密码
	 */
	public User(String userName, Integer age, String password) {
		this.userName = userName;
		this.age = age;
		this.password = password;
	}

	/**
	 * 带参数的构造函数
	 * 
	 * @param map
	 *            参数
	 */
	public User(Map<String, Object> map) {
		if (map == null) {
			throw new IllegalArgumentException("user");
		}
		this.userName = String.valueOf(map.get("userName"));
		this.age = Integer.valueOf(String.valueOf(map.get("age")));
		this.password = String.valueOf(map.get("password"));
	}

	@Override
	public String toString() {
		return "[ Name = " + this.userName + " | age = " + this.age + " | Password = " + this.password + " ]";
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}


ReflectTest代码:

package reflect;

import java.util.HashMap;
import java.util.Map;

public class ReflectTest {
	public static void main(String[] args) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userName", "殷建卫");
		map.put("age", 28);
		map.put("password", "123456");
		User user = null;
		try {
			// 创建对象
			user = ReflectUtils.getObject(map, User.class);
			System.out.println("user对象:" + user.toString());
			// 拷贝对象
			User userCopy = ReflectUtils.copy(user);
			System.out.println("userCopy对象:" + userCopy.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}

输出:

user对象:[ Name = 殷建卫 | age = 28 | Password = 123456 ]

userCopy对象:[ Name = 殷建卫 | age = 28 | Password = 123456 ]



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值