整体的三个测试代码块。我的需求是想一个方法可以根据传入对象的不同,进行公共的操作。

        这个例子创建了一个 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名称");
  }
}