Optional详解

在jdk1.8之前,我们每次判断一个对象是否为空,要么使用一些工具类,要么就直接使用if(aa == null);特别是直接使用aa == null被公认为是一种很low的方式。


public class OptionalDemo {

    public static void main(String[] args) {
        StudentService studentService = new StudentService();
        Student student = studentService.getStudent(1L);
        // 方式1
        if(student == null) {

        }
        // 方式2
        if(Objects.isNull(student)) {
            
        }
        
    }
}

那么我们是否能有其他方式来判断呢?

public static void main(String[] args) {
    StudentService studentService = new StudentService();
    Student student = studentService.getStudent(1L);
    Optional studentOptional = Optional.of(student);
    // 判断student是否为空
    if(studentOptional.isPresent()) {

    }

}

在jdk1.8的时候,提供了一个Optional类,它能够很轻松的判断一个对象是否为空,同时,不会出现null这个关键字。当然,这只是一个简单的特性,它还有很多高级的功能。

返回默认值

public static void main(String[] args) {
    StudentService studentService = new StudentService();
    Student student = studentService.getStudent(1L);
    student = Optional.ofNullable(student).orElse(new Student());
}

通过ofNullable和orElse便可以轻松的获取默认值

抛出异常

public static void main(String[] args) {
    StudentService studentService = new StudentService();
    Student student = studentService.getStudent(1L);
    student = Optional.ofNullable(student).orElseThrow(() -> new RuntimeException());
}

Optional存在的问题

我们来看一下这段代码

public abstract class AbstractResolverRegistry> implements ApplicationContextAware {
    private Map resolverMap = new HashMap<>();
    private ApplicationContext ctx;
    public V getResolver(K k1) {
        return Optional.ofNullable(resolverMap.get(k1)).orElse(resolverMap.get(getDefaultKey()));
    }
    @SuppressWarnings("unchecked")
    @PostConstructprivate void init() {
        Class clazz = getResolverClass();
        Collection list = ctx.getBeansOfType(clazz).values();
        if (list != null) {
            list.forEach((v1) -> {
                if (v1.getKey() instanceof String) {
                    String str = (String) v1.getKey();
                    if (StringUtils.isEmpty(str)) {
                        log.warn("配置为空,采用默认处理器:{},处理器类:{}", null, v1);
                        resolverMap.put(v1.getKey(), v1);
                    } else {
                        List strs = Arrays.asList(str.split(","));
                        for (String v : strs) {
                            log.info("处理器code:{},处理器类:{}", v, v1);
                            resolverMap.put((K) v, v1);
                        }
                    }
                } else {
                    if (v1.getKey() == null) {
                        log.info("配置为空,采用默认处理器:,处理器类:{}", v1);
                    } else {
                        log.info("非String类型的,业务处理器code:{},处理器类:{}", v1.getKey(), v1);
                    }
                    resolverMap.put(v1.getKey(), v1);
                }
            });
        }
        log.info("初始化classType={},resolverRegistry.length={}", new Object[]{clazz, list != null ? list.size() : 0});
    }
    /**
     * 注册器容器的类型
     *
     * @return
     */protected abstract Class getResolverClass();
    /**
     * @see ApplicationContextAware#setApplicationContext(ApplicationContext)
     */@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ctx = applicationContext;
    }
    /**
     * 获取默认处理器
     *
     * @return
     */protected abstract K getDefaultKey();
}

注:代码详情见策略模式的最佳实践方式-今日头条

return Optional.ofNullable(resolverMap.get(k1)).orElse(resolverMap.get(getDefaultKey()));这段代码的意思就是通过k1获取不到处理器的时候,便获取默认的处理器,但是,当有些实现类没有默认处理器,同时抛出异常的时候

public class PayServiceRegistry extends AbstractResolverRegistry {
    /**
     * 注册器容器的类型
     *
     * @return
     */@Overrideprotected Class getResolverClass() {
        return PayService.class;
    }
    /**
     * 获取默认处理器
     *
     * @return
     */@Override
     protected String getDefaultKey() {
        throw new RuntimeException("无默认支付方式");
    }
}

看起来这段代码没有问题,就是当k1获取不到相应的处理器时,便抛出异常,但是,当运行这段代码代码时,无论对应的处理器是否存在,都会抛出异常,原因就是orElse中的代码,无论ofNullable中的对象是否为空,都会执行,因此我们在使用Optional的时候,必须考虑这个问题。

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章