利用反射既可以获取也可以写入,首先咱们先写几个获取的例子。
一:利用反射修改各数据(利用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改为geggegegege
resultField.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);
}
}