整体的三个测试代码块。我的需求是想一个方法可以根据传入对象的不同,进行公共的操作。
这个例子创建了一个 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名称");
}
}