前言
业务中取对象某个值时,经常会遇到对象不存在。当然只有一层对象嵌套的时候,使用Optional.ofNullable是最简单的。那要是我的对象嵌套了5层、10层,别惊讶,千奇百怪的业务总有会遇到的。要取最底层的某个值,那Optional就要写老长一串了,这就比较头疼了。
想法
还是利用反射,一层一层剥开你对象的心,看Ta是不是真心。
如要拿到a对象中有个b属性对象中有个c属性的值,可以传字符串“b.c”构造get方法利用反射获取对现象值
为什么说还是“还是利用反射”呢??看过我博客的人都知道,我的很多轮子都是用的反射,反射真强大!!如果能用的很熟练,会简化很多的撸码工作。相信我、没戳的。
利用反射的轮子😜
代码
层级对象
/**
* 学生类
*
* @author MinWeikai
* @date 2021/4/3 12:30
*/
@Builder
@Data
public class Student {
private String name;
private Schoolbag bag;
}
/**
* 书包类
*
* @author MinWeikai
* @date 2021/4/3 12:31
*/
@Builder
@Data
public class Schoolbag {
private String color;
private PencilCase pencilCase;
}
/**
* 铅笔盒
*
* @author MinWeikai
* @date 2021/4/3 12:55
*/
@Builder
@Data
public class PencilCase {
private String name;
private Integer num;
}
MyOptional工作类
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mwk.entity.Schoolbag;
import com.mwk.entity.Student;
import java.util.Objects;
import java.util.Optional;
/**
* @author MinWeikai
* @date 2021/4/3 12:57
*/
public final class MyOptional {
/**
* 获取层级对象的值通过层级属性
*
* @param <T>
* @param source 源对象
* @param filed 可为层级属性,属性名用小圆点.分隔
* @param vClass 属性类型
* @return
*/
public static <T> T getValueByField(Object source, String filed, final Class<T> vClass) {
Objects.requireNonNull(filed);
String[] filedNames = filed.split("\\.");
Object oldTemp;
if (filedNames.length == 1) {
oldTemp = ReflectionUtil.invokeGetterMethodNoThrowException(source, filed);
return new ObjectMapper().convertValue(oldTemp, vClass);
}
oldTemp = ReflectionUtil.invokeGetterMethodNoThrowException(source, getFirstStrByPoint(filed));
if (Objects.isNull(oldTemp)) {
return null;
}
oldTemp = getValueByField(oldTemp, getEndStrByPoint(filed), vClass);
return new ObjectMapper().convertValue(oldTemp, vClass);
}
/**
* 获取层级对象的值通过层级属性
* 被Optional修饰,可使用Optional中方法处理结果值
*
* @param source
* @param filed
* @param vClass
* @param <T>
* @return
*/
public static <T> Optional<T> ofNullable(Object source, String filed, final Class<T> vClass) {
return Optional.ofNullable(getValueByField(source, filed, vClass));
}
private static String getFirstStrByPoint(String str) {
return str.substring(0, str.indexOf("."));
}
private static String getEndStrByPoint(String str) {
return str.substring(str.indexOf(".") + 1);
}
public static void main(String[] args) {
Student student = new Student("李明",
new Schoolbag("黄色",
null));
// new PencilCase("中性笔", 2)));
System.out.println(getValueByField(student, "name", String.class));
System.out.println(getValueByField(student, "bag", Schoolbag.class));
System.out.println(getValueByField(student, "bag", Schoolbag.class).getColor());
System.out.println(getValueByField(student, "bag.color", String.class));
System.out.println(getValueByField(student, "bag.pencilCase.num", Integer.class));
// 随意测试值,找不到应该为null
System.out.println(getValueByField(student, "ww.ee.num", Integer.class));
System.out.println(getValueByField(student, "bag.ee.num", Integer.class));
System.out.println(getValueByField(null, "bag.ee.num", Integer.class));
System.out.println("-----------被Optional修饰的方法------------");
System.out.println(ofNullable(student, "bag", Schoolbag.class).map(Schoolbag::getColor).orElse("无色"));
System.out.println(ofNullable(student, "name", String.class));
System.out.println(ofNullable(student, "bag", Schoolbag.class).isPresent());
System.out.println(ofNullable(null, "bag.ee.num", Integer.class).orElse(0));
System.out.println(ofNullable(null, "bag.ee.num", Integer.class).get());
}
}
方法中用到了一个反射方法工具