博客
关于我
Optional用法与争议点
阅读量:795 次
发布时间:2023-02-24

本文共 3163 字,大约阅读时间需要 10 分钟。

Java Optional的用法与争议

在Java编程中, NullPointerException(NPE)无疑是最常见的异常类型之一。处理null值的逻辑往往让代码显得冗长且难以阅读。为了简化这种逻辑,Java 8引入了Optional类,它不仅可以帮助程序员避免null指针异常,还能在某些场景中简化代码逻辑。本文将详细探讨Optional的用法与争议。

创建Optional

Optional类主要用于处理null值,可以避免代码中嵌套的null判断。以下是创建Optional的几种方法:

ofNullable()方法

ofNullable()方法用于创建一个Optional,传入的值可以是null或不是null。这种方法非常适合处理可能返回null的方法调用结果。

of()方法

of()方法用于创建一个Optional,传入的值不可能是null。如果传入null,会抛出NullPointerException。这一方法主要用于那些返回值必须是Optional的场景,例如方法返回类型为Optional的方法。

empty()方法

empty()方法用于创建一个空的Optional。这种方法通常用于返回值必须是Optional的场景,例如方法返回类型为Optional的方法,但返回值不需要具体的逻辑处理。

判空

Optional提供了多种方法来处理null值。以下是常用的判空方法:

ifPresent()方法

ifPresent()方法用于检查Optional是否包含值。如果Optional不为空,则执行传入的Consumer函数。如果Optional为空,则不执行任何操作。这种方法非常适合在不需要具体操作的情况下判断Optional是否为空。

isPresent()方法

isPresent()方法用于简单地判断Optional是否为空。如果 Optional 不为空,则返回true;否则返回false。这种方法比直接调用Optional对象是否为空更具可读性。

取值

Optional提供了多种方法来获取其值:

get()方法

get()方法用于获取Optional中的值。如果Optional为空,则抛出NoSuchElementException异常。这一方法通常用于需要确保Optional不为空的场景,例如在函数式处理中使用。

orElse()方法

orElse()方法用于在Optional为空时返回一个默认值。可以通过传入一个函数来指定默认值。例如:

String name = nameOpt.orElse("未命名");

orElseGet()方法

orElseGet()方法与orElse()方法类似,但它接受一个函数,该函数用于生成默认值。这种方法通常用于需要计算默认值的场景。例如:

BigDecimal amount = amountOpt.orElseGet(() -> calcDefaultAmount());

orElseThrow()方法

orElseThrow()方法用于在Optional为空时抛出一个指定的异常。这一方法可以避免在处理null值时出现意外的NPE异常。例如:

Optional

userOpt = getUser(userId);User user = userOpt.orElseThrow(() -> new NullPointerException("userId:" + userId));

这种方法与传统的try-catch逻辑相比,代码更加简洁,但需要确保抛出的异常足够有用,以便定位问题。

函数式处理

Optional提供了多种函数式方法来处理其值:

map()方法

map()方法用于将Optional中的值进行转换。可以通过传入一个函数来对值进行变换。例如:

String userCode = Optional.ofNullable(order) .map(Order::getUser) .map(User::getUserCode) .map(String::toUpperCase) .orElse("");

flatMap()方法

flatMap()方法与map()方法类似,但它接受一个函数,该函数返回一个Optional。这种方法适合在多个步骤中链式调用。例如:

Optional

userIdOpt = Optional.ofNullable(order) .flatMap(Order::getUser) .flatMap(User::getUserId) .orElse(empty());

filter()方法

filter()方法用于对Optional中的值进行过滤。如果Optional中的值满足过滤条件,则返回该值,否则返回空Optional。例如:

String name = nameOpt.filter(StringUtils::isNotBlank) .orElse("");

争议点

虽然Optional在处理null值方面非常有用,但它也引发了一些争议。以下是常见的争议点:

1. **过度使用**:有些开发者习惯性地使用Optional,对于根本不需要处理null值的场景,也使用Optional,这会增加代码复杂度。

2. **增加编码负担**:使用Optional后,调用方需要处理Optional的值,这可能会增加调用方的编码负担,尤其是当调用方不需要处理null值时。

3. **选择使用Optional的场景有限**:Optional最好用于返回值为Optional的方法,或者在多个属性获取时使用。对于字段或方法参数,通常不建议使用Optional。

4. **代码可读性问题**:虽然Optional的链式调用方式提高了代码的可读性,但如果滥用,可能会导致代码变得难以维护。

适用场景

以下是一些适合使用Optional的场景:

1. **返回值为Optional**:当一个方法的返回类型为Optional时,使用Optional可以避免返回null值的问题。

2. **多层属性获取**:在获取多个嵌套对象的属性时,使用Optional可以简化代码逻辑。例如:

Order order = getOrderById(orderId);String userCode = Optional.ofNullable(order) .map(Order::getUser) .map(User::getUserCode) .map(String::toUpperCase) .orElse("");

3. **函数式处理值**:在需要对值进行多次转换或处理时,使用Optional的链式方法可以简化代码逻辑。

4. **避免NPE异常**:通过使用Optional,可以避免在处理null值时出现NPE异常。例如,在获取用户信息时:

User user = Optional.ofNullable(order) .map(Order::getUser) .orElseThrow(() -> new NullPointerException("订单不存在"));

总结

Java Optional在处理null值方面提供了方便,但也需要谨慎使用。它适合用于返回值为Optional的方法,或者在需要链式处理多个属性的场景中使用。然而,在字段或方法参数中使用Optional可能会增加编码负担,甚至导致代码难以维护。因此,在选择是否使用Optional时,需要根据具体场景进行权衡。只有在确实需要处理null值且能提升代码可读性的情况下,才应该选择使用Optional。

转载地址:http://vipfk.baihongyu.com/

你可能感兴趣的文章
Openlayers实战:加载Bing地图
查看>>
Openlayers实战:绘制图形,导出geojson文件
查看>>
Openlayers实战:绘制图形,导出KML文件
查看>>
Openlayers实战:绘制多边形,导出CSV文件
查看>>
Openlayers实战:绘制带箭头的线
查看>>
Openlayers实战:自定义放大缩小,显示zoom等级
查看>>
Openlayers实战:自定义版权属性信息
查看>>
Openlayers实战:输入WKT数据,输出GML、Polyline、GeoJSON格式数据
查看>>
Openlayers实战:选择feature,列表滑动,定位到相应的列表位置
查看>>
Openlayers实战:非4326,3857的投影
查看>>
Openlayers高级交互(1/20): 控制功能综合展示(版权、坐标显示、放缩、比例尺、测量等)
查看>>
Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
查看>>
Openlayers高级交互(11/20):显示带箭头的线段轨迹,箭头居中
查看>>
Openlayers高级交互(12/20):利用高德逆地理编码,点击位置,显示坐标和地址
查看>>
Openlayers高级交互(13/20):选择左右两部分的地图内容,横向卷帘
查看>>
Openlayers高级交互(14/20):汽车移动轨迹动画(开始、暂停、结束)
查看>>
Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
查看>>
Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
查看>>
Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
查看>>
Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口
查看>>