可选vs抛出exception

是不是因为Java 1.8返回Optional对象比抛出exception更可取? 我越来越多地看到这样的代码:

  public Optional get(int i) { // do somtething Object result = ... Optional.ofNullable(result); } 

而不是这个:

 public Object get(int i) { if(i=size) { throw new IndexOutOfBoundsException("Index: " + i + ". Size: " + size); } // do somtething Object result = ... return result; } 

是否意味着我们需要忘记旧方法并使用新方法? 什么是Optional的适合?

您提供的示例不是 Optional的适当用法。 空Optional表示由于调用者无法预测的原因而缺少的值。 它是法律调用方法的结果。

您作为“旧习惯用法”呈现的代码会执行输入validation,如果输入无效,则会抛出未经检查的exception。 即使您引入Optional,此行为也应保持不变。 唯一的区别是Object get(i)的返回值可能为null,而Optional get(i)的返回值永远不为null,因为Optional实例的特殊状态表示缺少值。

返回Optional而不是可空值的方法的优点是消除了样板代码,该代码必须在尝试对返回值执行任何操作之前进行例行的空检查。 纯粹在方法中使用Optional有许多其他优点。 例如:

 static Optional componentType(Type type) { return Optional.of(type) .filter(t -> t instanceof ParameterizedType) .map(t -> (ParameterizedType) t) .filter(t -> t.getActualTypeArguments().length == 1) .filter(t -> Optional.of(t.getRawType()) .filter(rt -> rt instanceof Class) .map(rt -> (Class) rt) .filter(Stream.class::isAssignableFrom) .isPresent()) .map(t -> t.getActualTypeArguments()[0]); 

这里一个重要的好处是完美的范围控制:在每个新范围内,对于适合于该处理阶段的类型的变量,重复使用相同的名称。 因此,不是在其使用寿命到期后被迫在范围内使用变量,而是为每个后续变量创建一个新名称,使用这个习惯用法,我们可以获得我们需要进行的精确最小值。

只是为了感兴趣,你可以完全按照Optional来实现equals

 @Override public boolean equals(Object obj) { return Optional.ofNullable(obj) .filter(that -> that instanceof Test) .map(that -> (Test)that) .filter(that -> Objects.equals(this.s1, that.s1)) .filter(that -> Objects.equals(this.s2, that.s2)) .isPresent(); } 

虽然我发现这个成语非常干净和可读,但它目前还没有足够优化,不适合作为一个值得考虑的选择。 但是,Java的未来版本可能会使这一点变得可行。

可以平等地滥用exception,空值和可选项。 在这种特殊情况下,我认为你可能会滥用可选项,因为你默默地隐藏了一个前提条件违规并将其转换为正常返回。 在收到代码中的空选项后,调用者无法区分“我正在寻找的东西不在那里”和“我问了一个无效的问题。”

因为Optional是新的,所以它也有被过度使用的趋势; 希望随着时间的推移,正确的模式将被内化。

可选是null对象模式的示例; 当“没有任何东西”是合理的预期结果时,它提供了一种安全的方式来说“没有任何东西”。 (返回空数组或空集合是这些域中的类似示例。)是否要表示“空白/可选”与“exception”之间的“没有”通常是“没有”是否是通常预期的情况的函数,或者是否特殊。 例如,如果映射不存在,没有人希望Map.get抛出exception; map-not-present是一种预期的,而非例外的结果。 (如果我们在1997年有OptionalMap.get可能会返回一个Optional 。)

我不知道你在哪里听到的建议是,Optional比例外更可取,但是谁告诉你这是不明智的。 如果你之前抛出exception,你可能仍然应该抛出exception; 如果之前返回null,则可以考虑返回Optional

在可能出现错误的情况下,合适的数据类型是Try。

Try不使用抽象’present’或’empty’,而是使用抽象’失败’或’成功’。

由于Java 8没有开箱即用,因此有必要使用一些3.方库。 (也许我们会在Java 9中看到它添加?)

尝试Java