猿问

Java 可选和 orElse

我是 Java 选项的新手,但我看到另一个开发人员编写的代码,但我不明白:


String t = null;

Optional.ofNullable("notnull")

    .orElse(

        Optional.ofNullable(t).orElseThrow(() -> new Exception("MyException"))

    );

为什么这段代码会抛出异常?为什么它甚至会转到“orElse”分支?


这是因为一些奇怪的执行顺序吗?那么在评估 orElse 分支之前没有设置第一个可选值?


qq_笑_17
浏览 209回答 7
7回答

慕田峪7331174

永远不会调用流orElse,但会执行方法本身。这意味着方法参数也传递给它。Optional.ofNullable(t).orElseThrow(() -> new Exception("MyException"))因此无论传递给第一次调用的值如何,都会调用该部分Optional.ofNullable。如果你不希望这种情况发生,你需要传递Supplier这样的信息:String t = null;Optional.ofNullable("notnull")    .orElseGet(        () -> Optional.ofNullable(t).orElseThrow(() -> new RuntimeException("MyException"))    );orElseGet只有在调用流时才会调用供应商。请注意,您需要一个RuntimeException而不是已检查的异常才能脱离供应商。

沧海一幻觉

那是因为里面的代码orElse()总是会被评估。换句话说,即使您指定非空,它也会被执行Optional,所以这就是Exception抛出的原因。如果您查看Java 可选 – orElse() 与 orElseGet()orElse()文章的部分,您可以在他们的示例中看到这一点,其中显示:我们可以很容易地推断出 orElse() 的参数即使在具有非空 Optional 的情况下也会被评估。

慕妹3146593

我真的很想知道为什么这段代码是以这种方式编写的。似乎它需要触发一个异常,并在可选中添加一个显式的 NULL 值。正如已经说过的,当使用orElse()而不是orElseGet()方法时,无论 T 的值如何(例如Optional<T>)都会被评估。我会使用更好的时尚和理解:String value = "notnull"; // could be nullOptional.ofNullable(value)&nbsp; &nbsp; .orElseThrow(MyException::new);如果值为 NULL,则会触发异常。注意:您可以使用方法引用来调用异常

largeQ

你写的是这样的:String t = null;String myException = Optional.ofNullable(t).orElseThrow(() -> new Exception("MyException"));Optional.ofNullable("notnull").orElse(myException);在您知道您的值是否为空之前,部分已被评估。如果您想要评估,请考虑orElse方法。Optional"Lazy"orElseGet

胡说叔叔

关于Optional ,您应该注意以下几点:如果已知被包装的值是否为空,请使用Optional.of()或Optional.empty()。如果不确定(例如值是从其他地方获得的变量),请使用Optional.ofNullable()Optional.orElse()和Optional.orElseGet()之间有一个重要的区别。orElse接受一个已经计算出的值,如果提供了一个表达式,它会立即执行并立即计算。这发生在有问题的代码中。因此,这个 else 变体应该用于已经可用的值或原语。orElseGet接受一个供应商函数,该函数仅在评估可选链并请求替代值时运行。当替代值的生成或计算成本昂贵时应使用此方法。// FineOptional<String> name = Optional.of(someValue).orElse("defaultName");// But this:Optional<String> name = Optional.of(someValue).orElse(db.queryName());// Is better written as following, as it saves you from an expensive operationOptional<String> name = Optional.of(someValue).orElseGet(() -> db.queryName());

慕丝7291255

问题是按执行顺序。它尝试计算 .orElse(...) 的值并在 .orElseThrow 上抛出 MyException。换句话说,如果 t 不为空,执行流程如下:1) 计算值Optional.ofNullable(t).orElseThrow(()&nbsp;->&nbsp;new&nbsp;Exception("MyException"))2) 使用 (1) 中的值Optional.ofNullable("notnull").orElse(...)

潇潇雨雨

结果是预料之中的,因为在 Java 中,在调用带有参数的方法之前,JVM 之前所做的事情是评估参数值。那就是调用的参数值.orElse():Optional.ofNullable(t).orElseThrow(()&nbsp;->&nbsp;new&nbsp;Exception("MyException"))由于t引用null,因此预计会抛出异常。
随时随地看视频慕课网APP

相关分类

Java
我要回答