Optional用法与争议点
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。简介
要说Java中什么异常最容易出现,我想NullPointerException一定当仁不让,为了解决这种null值判断问题,Java8中提供了一个新的工具类Optional,用于提示程序员注意null值,并在特定场景中简化代码逻辑。
比如下面一段取深层属性值的代码:
Order order = getOrderById(orderId);
String userCode = "";
if(order != null){
if(order.getUser() != null){
if(order.getUser().getUserCode() != null){
userCode = order.getUser().getUserCode().toUpperCase();
}
}
}这种场景还比较常见,但深层嵌套的if判断,让代码阅读者压力倍增。
看看用Optional后的写法,如下:
Order order = getOrderById(orderId);
String userCode = Optional.ofNullable(order)
.map(Order::getUser)
.map(User::getUserCode)
.map(String::toUpperCase)
.orElse("")链式调用的写法,让代码可读性增强了不少,不用判断null,是因为Optional在内部已经做了null值判断了!那我们来看看Optional都有哪些用法吧。
创建Optional
ofNullable()方法
创建一个Optional,传入的值可以是null或不是null。
of()方法
得到一个Optional,明确知道传入的值不是null时用这个,如果传null会报错NullPointerExcepiton。
其实值不为null一般是没必要使用Optional的,这个应该是用于特殊场景,比如方法返回值必须是一个Optional。
empty()方法
得到一个空的Optional,一般也用于返回值必须是Optional的场景。
判空
ifPresent()方法
判断是否有值,注意,这个方法虽然看起来挺好用的,但它不太应该是使用Optional时第一个使用的方法,如下:
if(opt.ifPresent()){
...
}
if(obj != null) {
...
}这两个代码除了写法不一样,对于代码可读性方面没有根本区别!
取值
get()方法
获取Optional的值,当没有值时会抛出一个NoSuchElementException异常。
https://img2022.cnblogs.com/blog/2792815/202211/2792815-20221106204441181-1832707632.png
同样的,它也不太应该是使用Optional时的第一个使用的方法,因为抛NoSuchElementException与抛NullPointerException并没有太大区别。
orElse方法
没有值时会返回指定的值。
String name = nameOpt.orElse("");orElseGet方法
同上,不过参数变成了一个提供默认值的lambda函数,这用在取指定值需要一定代价的场景,如下:
BigDecimal amount = amountOpt.orElseGet(() -> calcDefaultAmount());orElseThrow方法
没有值时抛出一个指定的异常,如下:
Optional<User> userOpt = getUser(userId);
User user = userOpt.orElseThrow(() -> new NullPointerException("userId:" + userId));可能会有人疑问,你还是抛出了一个NPE异常,和不使用Optional有啥区别?区别是这个NPE异常会告诉你哪个userId查不到数据,方便定位问题,而jvm抛出的NPE是没有这个信息的。
函数式处理
<strong>ifPresent(Consumer
页:
[1]