【发布时间】:2015-04-29 01:37:46
【问题描述】:
在 Java 8 中,您可以返回 Optional 而不是 null。 Java 8 文档说 Optional 是“一个容器对象,它可能包含也可能不包含非空值。如果存在值,isPresent() 将返回 true,而 get() 将返回该值。”
在实践中,为什么这很有用?
另外,在任何情况下使用null 会更好吗?性能怎么样?
【问题讨论】:
-
性能怎么样?
在 Java 8 中,您可以返回 Optional 而不是 null。 Java 8 文档说 Optional 是“一个容器对象,它可能包含也可能不包含非空值。如果存在值,isPresent() 将返回 true,而 get() 将返回该值。”
在实践中,为什么这很有用?
另外,在任何情况下使用null 会更好吗?性能怎么样?
【问题讨论】:
在实践中,为什么这很有用?
例如,假设你有这个整数流并且你正在做一个过滤:
int x = IntStream.of(1, -3, 5)
.filter(x -> x % 2 == 0)
.findFirst(); //hypothetical assuming that there's no Optional in the API
您事先并不知道过滤操作会删除 Stream 中的所有值。
假设 API 中没有 Optional。在这种情况下,findFirst 应该返回什么?
唯一可能的方法是抛出一个异常,例如NoSuchElementException,这在 IMO 中相当烦人,因为我认为它不应该停止你的程序的执行(或者你必须捕获异常,也不是很方便),过滤标准可能比这更复杂。
使用Optional,由调用者检查Optional 是否为空(即您的计算是否产生了值)。
对于引用类型,您还可以返回 null(但在您仅过滤 null 值的情况下,null 可能是一个可能的值;所以我们回到异常情况)。
关于非流的使用,除了防止 NPE 之外,我认为它还有助于设计一个更明确的 API 来说明值可能存在或不存在。例如考虑这个类:
class Car {
RadioCar radioCar; //may be null or not
public Optional<RadioCar> getRadioCar() {
return Optional.ofNullable(radioCar);
}
}
在这里,您清楚地对呼叫者说,车内的收音机是可选的,它可能存在或不存在。
【讨论】:
Optional<T> 而不是 null 的令人信服的理由。顺便说一句,Optional<T> 可以向开发人员提供合同提示,但适当的文档也可以...在一天结束时,您仍在检查该值是否为空,然后再对其进行操作。您刚刚将语义从 if (value == null) 更改为 if (optionalValue.isPresent())。而且您已经产生了几个方法调用的开销。
null 调用方法的方式来表示数据。如果没有 Optionals,这不仅是可能的,而且非常容易。换句话说,您可以避免草率的逻辑和愚蠢的错误。它与方便或冗长几乎没有关系。
在最初设计 Java 时,通常使用一个特殊的值,通常称为 null 来表示特殊情况,例如 我找不到你要找的东西。 Java 采用了这种做法。
从那时起,有人建议将这种做法视为一种反模式,尤其是对于对象而言,因为这意味着您必须在代码中乱扔空检查以实现可靠性和稳定性。例如,当您想将null 放入集合中时,这也是一种痛苦。
现代态度是使用一个特殊的对象,它可能持有也可能不持有价值。这样你就可以安全地创建一个,而不是用任何东西填充它。在这里,您看到 Java 8 通过提供 Optional 对象来鼓励这种最佳实践。
【讨论】:
Optional.isPresent 的空检查,那么它的实用性将受到限制(仍然在调用站点明确声明该值可能不存在,这很好);真正的力量来自能够推迟错误处理(无值)到以后的时间和链接 map/flatMap/filter 等方法而无需 if/else 块。
@NonNull 的代码库。然后 Optional 可以发生 null 的地方。这提供了更安全的程序,这也是 Java 作为语言之前的发展方向(例如 C++ refs)。 Optional 通过将 map 和 flatMap 与 lambda 一起使用,消除了对条件的需求。像这样构建代码可确保不会忽略任何空检查。只是不允许调用 isPresent 并且您必须映射以获取数据并且您不会出错。
Optional 可帮助您处理可用或不可用的变量,并避免检查空引用。
【讨论】:
Optional#isPresent 方法安全检查
null 检查是程序员必须有意识地做的事情,Java 在编译时不会捕捉到这一点。 Optional 帮助确保使用Optional的人知道该值可能不存在,并且在某些情况下强制程序员执行@987654325的等效操作@检查代码甚至编译。