利用反射既可以获取也可以写入,首先咱们先写几个获取的例子。
一:利用反射修改各数据(利用resultField.set修改)
首先定义实体类
public class Dog {private String dogUser;private int age;
把DogUser
的"hahaha"
改为"geggegegege"
Dog dog = new Dog();
dog.setAge(21);
dog.setDogUser("hahaha");
Object name = getValueByKey(dog, "dogUser");
System.out.println("获取到的属性名dogUser:"+name);
利用反射修改属性的工具类
public static <T> Object getValueByKey(T t, String key) {Class clazz = t.getClass();Field[] fields = clazz.getDeclaredFields();Field resultField = Arrays.stream(fields).filter(field -> field.getName().equals(key)).findFirst().get();Object obj = null;resultField.setAccessible(true);try {//把dogUser属性值从hahaha改为geggegegegeresultField.set(t,"geggegegege");obj = resultField.get(t);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return obj;}
测试结果:
二:利用反射获取各种形式的数据
首先定义实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Person {private String name = "zhangsan";private byte sex = 1;private int age = 18;private String introduce = "niuBility";
}
在定义一个接口常量
public interface Constant {int CONFIG_INT1 = 1;int CONFIG_INT2 = 2;int CONFIG_INT3 = 3;String CONFIG_STRING1 = "1";String CONFIG_STRING2 = "2";String CONFIG_STRING3 = "3";
}
1:获取单个对象的所有键值对(变量名-变量值)
通过泛型参数限定传入一个对象,该方法传入一个对象,返回该对象所有的属性-值。
注意:这里Collectors.toMap(key,value)中的value值不能为空,若对象属性值存在为空的情况,则会抛出空指针异常,查看toMap()方法源码,发现在map集合进行merge合并时进行了非空判断操作,如下:
故这里使用Optional进行空值的包装,在为空时用0代替(看具体业务场景)。ps: 做map转换记得写键值冲突策略,养成好习惯,这里采用后者覆盖,(k1, k2) -> k2。
/*** 获取单个对象的所有键值对** @param t* @param <T>* @return*/public static <T> Map<String, Object> getKeyAndValue(T t) {Map<String, Object> map = Maps.newHashMap();Class clazz = (Class) t.getClass();Field[] fields = clazz.getDeclaredFields();map = Arrays.stream(fields).collect(Collectors.toMap(Field::getName, field -> {Object resultObj = null;field.setAccessible(true);try {resultObj = field.get(t);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return Optional.ofNullable(resultObj).orElse(0);}, (k1, k2) -> k2));return map;}
测试用例:
Map<String, Object> result1 = ReflectObjectUtil.getKeyAndValue(new Person());
测试结果:
2:获取单个对象指定键的值
第一种方式:
/*** 获取单个对象指定键的值** @param t* @param key* @param <T>* @return*/public static <T> Object getValueByKey(T t, String key) {Class clazz = t.getClass();Field[] fields = clazz.getDeclaredFields();Field resultField = Arrays.stream(fields).filter(field -> field.getName().equals(key)).findFirst().get();Object obj = null;resultField.setAccessible(true);try {obj = resultField.get(t);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return obj;}
测试用例:
Object result2 = ReflectObjectUtil.getValueByKey(new Person(), "name");
测试结果:
第二种方式(利用反射Method的invoke方法):
实体类:
public class Dog{private String name;private int age;
Dog dog = new Dog();
dog.setAge(21);
dog.setName("哈哈");
//第二种方式
Object name = getFieldValueByName("name", (Object) dog);
System.out.println("获取到的属性名:"+name);
public static Object getFieldValueByName(String fieldName, Object o) {try {String firstLetter = fieldName.substring(0, 1).toUpperCase();String getter = "get" + firstLetter + fieldName.substring(1);Method method = o.getClass().getMethod(getter, new Class[] {});Object value = method.invoke(o, new Object[] {});return value;} catch (Exception e) {return null;}}
测试结果:
3:获取多个对象的所有键值对
/*** 获取多个对象的所有键值对** @param objects* @return*/public static List<Map<String, Object>> getKeyAndValues(List<Object> objects) {return objects.stream().map(obj -> {Class clazz = obj.getClass();return Arrays.stream(clazz.getDeclaredFields()).collect(Collectors.toMap(Field::getName, field -> {Object resultObj = null;field.setAccessible(true);try {resultObj = field.get(obj);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return Optional.ofNullable(resultObj).orElse(0);}, (k1, k2) -> k2));}).collect(Collectors.toList());}
测试用例:
List<Map<String, Object>> result3 = ReflectObjectUtil.getKeyAndValues(Arrays.asList(new Person(), new Person()));
测试结果:
4:获取多个对象指定键的所有值
/*** 获取多个对象指定键的所有值** @param objects* @param key* @return*/public static List<Object> getValuesByKey(List<Object> objects, String key) {return objects.stream().map(obj -> {Class clazz = obj.getClass();return Arrays.stream(clazz.getDeclaredFields()).filter(field -> field.getName().equals(key)).map(field -> {Object resultObj = null;field.setAccessible(true);try {resultObj = field.get(obj);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return resultObj;}).collect(Collectors.toList());}).collect(Collectors.toList());}
测试用例:
List<Object> result4 = ReflectObjectUtil.getValuesByKey(Arrays.asList(new Person(), new Person()), "name");
测试结果:
5:获取静态变量(以下适用与类或接口参数)
/*** 获取静态变量** @param clazz* @param key* @return*/public static Object getValueByKey(Class<?> clazz, String key) {Field[] fields = clazz.getDeclaredFields();Field result = Arrays.stream(fields).filter(field -> key.equals(field.getName())).findFirst().get();Object obj = null;try {obj = clazz.getField(result.getName()).get(null);} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();}return obj;}
测试用例:
String result5 = ReflectObjectUtil.getValueByKey(Constant.class, "CONFIG_INT1").toString();
测试结果:
6:获取类或接口中所有的常量
/*** 获取类或接口中所有的常量** @param clazz* @return*/public static Map<String, Object> getFinalValues(Class<?> clazz) {Field[] fields = clazz.getDeclaredFields();return Arrays.stream(fields).filter(field -> Modifier.isFinal(field.getModifiers())).collect(Collectors.toMap(Field::getName, field -> {Object obj = null;try {obj = clazz.getField(field.getName()).get(null);} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();}return obj;}));}
测试用例:
Map<String, Object> result6 = ReflectObjectUtil.getFinalValues(Constant.class);
测试结果:
测试用例汇总:
public class Test1 {public static void main(String[] args) {Map<String, Object> result1 = ReflectObjectUtil.getKeyAndValue(new Person());Object result2 = ReflectObjectUtil.getValueByKey(new Person(), "name");List<Map<String, Object>> result3 = ReflectObjectUtil.getKeyAndValues(Arrays.asList(new Person(), new Person()));List<Object> result4 = ReflectObjectUtil.getValuesByKey(Arrays.asList(new Person(), new Person()), "name");String result5 = ReflectObjectUtil.getValueByKey(Constant.class, "CONFIG_INT1").toString();Map<String, Object> result6 = ReflectObjectUtil.getFinalValues(Constant.class);}
}