整体的三个测试代码块。我的需求是想一个方法可以根据传入对象的不同,进行公共的操作。
这个例子创建了一个 User 对象,有两个属性,分别是id和name。需要给这两个属性进行赋值操作。
而操作的方法则是公共的方法,不但是可以为这个对象操作,其他的对象只要有这两个属性也可以实现操作。
我之前一直不明白这个类型怎么去做控制,因为传入的对象是不同的。其实最核心的点是两个,一个是类类型的控制,第二个是反射赋值。
第一个类型控制(三种情况):
1.传入空对象,这个时候可以用 class<T> 去接,进行实例化并返回
2.传入已经定义好的对象,这个时候可以用他们的公共基类 Obejct 去接。
3.返回对象(我之前最迷的一点),可以用 <T> T 形式,表示返回的对象是一个泛型。可以方法处理完后再做转换处理。
第二个反射注入(两种):
1. 使用大家都耳熟能详的set方法注入,需要拿到方法参数
2. 拿到字段值直接使用反射工具里的set方法注入。
见详细的代码:
import lombok.Data; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 反射注入属性值 * @author wangdefa */ public class SetValue { //创建一个User对象 @Data static class User { private String id; private String name; } /** * 主方法用于调用测试,查看运行结果 * @param args * @throws IllegalAccessException * @throws InstantiationException * @throws NoSuchMethodException * @throws InvocationTargetException */ public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { User user = (User) setVal(User.class); System.out.println(user.toString()); user = setMethodVal(User.class); System.out.println(user.toString()); setMethodValVoid(user); System.out.println(user.toString()); } /** * 反射注入值-通过属性字段进行赋值 * * @param tClass * @return * @throws IllegalAccessException * @throws InstantiationException */ private static Object setVal(Class<User> tClass) throws IllegalAccessException, InstantiationException { Object obj = tClass.newInstance(); //getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。 //getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。 Field[] fields = obj.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { //成员变量为private,故必须进行此操作 //以通过反射获取私有变量的值,在访问时会忽略访问修饰符的检查 fields[i].setAccessible(true); if (fields[i].getName().equals("id")) { fields[i].set(obj,"1"); } else if (fields[i].getName().equals("name")){ fields[i].set(obj,"名字"); } } return obj; } /** * 反射注入值-通过属 set方法进行赋值 * * <T> T 表示返回值是一个泛型 * T 用于限制传递的数据类型(编译时才需要去确定的具体类型) * @param tClass * @return * @throws IllegalAccessException * @throws InstantiationException */ private static <T> T setMethodVal(Class<T> tClass) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { T obj = tClass.newInstance(); Method setId = obj.getClass().getMethod("setId", String.class); setId.invoke(obj, "2"); Method setName = obj.getClass().getMethod("setName", String.class); setName.invoke(obj, "名称"); return obj; } /** * 不同对象使用同一个方法操作相同的字段值(无参) * @param obj * @throws IllegalAccessException * @throws NoSuchMethodException * @throws InvocationTargetException */ private static void setMethodValVoid(Object obj) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { Method setId = obj.getClass().getMethod("setId", String.class); setId.invoke(obj, "3"); Method setName = obj.getClass().getMethod("setName", String.class); setName.invoke(obj, "3名称"); } }