java.util.Objects 与可选哪个更可取?
java.util.Objects vs Optional which is preferable?
java.util.Objects class 扩展了一些新方法
分别
Objects#requireNonNullElseGet() Java-9
。
两者都将 return 第一个参数,如果它是非空的,否则 returns 非空的第二个参数或 supplier.get()[ 的非空值=31=]
jshell> String nullStr = null;
nullStr ==> null
jshell> Objects.requireNonNullElse(nullStr,"lorem ipsum");
==> "lorem ipsum"
jshell> Objects.requireNonNullElseGet(nullStr,() -> "lorem ipsum");
==> "lorem ipsum"
但新功能与 Optional
class Optional#orElse and Optional#orElseGet
中已有的功能重叠
jshell> Optional.ofNullable(nullStr).orElse("lorem ipsum");
==> "lorem ipsum"
jshell> Optional.ofNullable(nullStr).orElseGet(() -> "lorem ipsum");
==> "lorem ipsum"
Objects
中的新方法与相应的 Optional
方法之间的唯一区别是供应商的第二个参数或值必须为非空,否则 Objects
抛出 NPE
:
jshell> Objects.requireNonNullElseGet(nullStr,() -> null);
| java.lang.NullPointerException thrown: supplier.get()
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElseGet (Objects.java:321)
| at (#15:1)
jshell> Objects.requireNonNullElse(nullStr,null);
| java.lang.NullPointerException thrown: defaultObj
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElse (Objects.java:301)
| at (#16:1)
对比Optional
jshell> Optional.ofNullable(nullStr).orElse(null);
==> null
jshell> Optional.ofNullable(nullStr).orElseGet(() -> null);
==> null
- 为什么 JDK 开发人员没有更新 Optional 中的现有方法
class?
- 为什么他们没有引入新方法(将抛出
NPE 如果第二个参数为 null) 到 Optional class?
- 我们现在应该用什么Optional或者Objects?
- 新方法是否使 Objects 比 Optional 更受欢迎,因为它们
将立即抛出 NPE 而不是稍后在代码中的某个地方
喜欢 Optional?
如果我有遗留代码,例如:
String str = null;
String result = str == null ? "other string" : str;
这只是一个方法内部的简单检查。我想使用最新的语言特性重构它。现在想想 Optional.orElse
和 Objects.requireNonNullOrElse
之间的区别,哪个更可取?
result = Optional.ofNullable(str).orElse("other string");
或
result = Objects.requireNonNullOrElse(str,"other string);
重点是:这两个方法签名明显不同:
public static <T> T requireNonNullElse(T obj, T defaultObj)
对比
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
第二种方法的 javadoc 为:
Returns 第一个参数,如果它是非空的,否则 returns 是 supplier.get() 的非空值。
换句话说:它使用您在此处提供给它的供应商。
所以,答案是:在您希望与供应商合作的情况下使用第二个版本;否则,您只需采用采用 "less complicated" 参数的该方法的 "more simple" 版本。
背后的原因:当您在两个选项之间做出决定时,您更喜欢/"less reader surprising" 更容易使用的那个。换句话说:当您可以不用时,为什么要提供供应商。
关于 Optional 的使用 - 请记住它们的 main 目标是用于 return 类型;不是方法参数(请参阅 以进一步阅读)。
然后:更新 class 交付的现有方法 "to the field" 几乎总是不行的。您绝对 不 想要更改已经公开并由您的客户使用的内容的语义;假设特定的语义。
Why haven't the JDK developers updated existing methods in Optional class?
因为这会引入一个会破坏许多现有程序的重大更改,并且因为如果需要,该方法应该允许获取 null。
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
可能是因为那样会使 API 更加复杂和臃肿,而没有明显的优势。如果你想确保你的代码不会 return null 意外地,你仍然可以用 requireNonNull 包装结果。
What should we use now Optional or Objects?
如果您需要从可选的 return 方法中提取值,请使用可选的方法。如果要确保满足不应为空的方法参数的前提条件,请使用 Object.requireXxx。 JDK 设计者从来没有提倡使用 Optional 来包装一个值并检查是否为 null。可选的是 return 个值。
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
参见前面的观点:您不使用这些方法来做同样的事情。
Q. Why haven't the JDK developers updated existing methods in Optional class?
一个。因为 Optional
class 是为了避免 NPE 而设计的。
Q. Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
一个。同样的答案。
Q. What should we use now Optional or Objects?.
一个。两个都。 Objects
用于简单的 "not null" 检查,Optional
用于链式操作,如 map
、flatMap
、`filter'。
Q. Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
一个。视情况而定。如果您已经将 Optional 作为某些方法的 return 值,那么最好使用 Optional.
所以要点是您是否喜欢使用 ifs 来检查是否为 null。如果你有一个方法可以接受可以是空值的参数,那么使用 Objects 会更有意义。使用 Optional 的唯一合理的地方是验证对 returns 可选结果的方法的调用。
开发人员希望使用更实用的方法来检查空值,因此为此目的使用结构 Optional.ofNullable
,这不是一个好的做法,因为它会产生垃圾。
您问题的最短答案 "which is preferable?" 一直是开发人员的最爱 "it depends" 因为 Objects::requireNonNullElse
和 Optional
涵盖不同的用例。
两种选择
在回答您的问题之前,我想先介绍一下这两种选择的背景。
Objects::requireNonNullElse
Objects::requireNonNull
确保调用的结果永远不会为空(因此得名)。通常用于简洁地验证构造函数或方法参数,让读者一眼就能验证return赋值的变量不能为null。
所以 Objects::requireNonNullElse
突然允许 null
不仅很奇怪,而且几乎没有用,因为:
// if requireNonNullGet would allow null as second argument,
// the following is true for all x (including null)
Objects.requireNonNullElse(x, null) == x
您可能会争辩说 requireNonNullElseGet
是不同的,因为它可能会调用一个函数,根据某些状态,该函数可能 return null
或不。这是真的,我认为它被考虑过,但是如果这三种情况中的一种实际上允许调用的最终结果是 null
,那么 requireNonNull...
API 会非常奇怪,即使名称说 需要非 null。
Optional
Optional
was designed as a return argument in cases where returning null
is very likely to cause NPEs (like for a Stream
's terminal operation, where it was first used). Although some developers prefer to use it in more cases (compare Stephen Colebourne's pragmatic approach and my strict approach) 没有人真正建议像您的演示那样使用它:
Optional.ofNullable(nullStr).orElse(null);
Optional.ofNullable(nullStr).orElseGet(() -> null);
Optional
是一种在类型系统中表达可能缺少某些东西的方式——它并不意味着可以替代 if
-null
-检查。从这个意义上说,orElse
或 orElseGet
是 Optional
回到可空类型世界的后门,有时 null
正是你想要使用的,如果某些东西不存在,所以他们接受 null
作为参数(或供应商的结果)是有意义的。
您的问题
现在我们可以回答您的问题了:
Why haven't the JDK developers updated existing methods in Optional class?
从概念上讲,这与 Optional
的用途背道而驰。但是,正如其他人所提到的,这将是一个向后不兼容的更改,因为调用 orElse(null)
会突然抛出异常。
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
API 仅在预期对现有代码进行相当大的改进时才会扩展。我在这里看不到。在许多情况下,orElse
获取调用者专门创建的参数作为空可选值的替代项——很少需要进行额外检查来验证它不是 null
。如果确实需要,请致电 orElse(requireNonNull(x))
.
What should we use now Optional or Objects?
如果您有一个变量(无论是本地变量、参数还是字段)并且您想确保它不为空,请使用 Objects
。如果你想要 return 一些东西,这可能是 null 考虑将它包装在 Optional
中。对创建 Optional
(而不是获取一个调用形式)并在同一链的末尾展开它的代码持怀疑态度。
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
我现在肯定很清楚,它们涵盖了不同的用例。但让我解决一下 "and not later on somewhere in the code like with Optional":无论您做什么,请确保在您的代码中检查您想要的可空性 属性(可以是 null
,也可以不是)。不要 return 你认为不可能的东西 null
但事实证明是因为你没有检查。如果发生这种情况,那不是 Optional
的错。
If I have a legacy code, something like:
String str = null;
String result = str == null ? "other string" : str;
绝对Objects.requireNonNullOrElse(str,"other string");
并考虑使用静态导入使其更具可读性。
java.util.Objects class 扩展了一些新方法
分别
Objects#requireNonNullElseGet() Java-9
。
两者都将 return 第一个参数,如果它是非空的,否则 returns 非空的第二个参数或 supplier.get()[ 的非空值=31=]
jshell> String nullStr = null;
nullStr ==> null
jshell> Objects.requireNonNullElse(nullStr,"lorem ipsum");
==> "lorem ipsum"
jshell> Objects.requireNonNullElseGet(nullStr,() -> "lorem ipsum");
==> "lorem ipsum"
但新功能与 Optional
class Optional#orElse and Optional#orElseGet
jshell> Optional.ofNullable(nullStr).orElse("lorem ipsum");
==> "lorem ipsum"
jshell> Optional.ofNullable(nullStr).orElseGet(() -> "lorem ipsum");
==> "lorem ipsum"
Objects
中的新方法与相应的 Optional
方法之间的唯一区别是供应商的第二个参数或值必须为非空,否则 Objects
抛出 NPE
:
jshell> Objects.requireNonNullElseGet(nullStr,() -> null);
| java.lang.NullPointerException thrown: supplier.get()
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElseGet (Objects.java:321)
| at (#15:1)
jshell> Objects.requireNonNullElse(nullStr,null);
| java.lang.NullPointerException thrown: defaultObj
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElse (Objects.java:301)
| at (#16:1)
对比Optional
jshell> Optional.ofNullable(nullStr).orElse(null);
==> null
jshell> Optional.ofNullable(nullStr).orElseGet(() -> null);
==> null
- 为什么 JDK 开发人员没有更新 Optional 中的现有方法 class?
- 为什么他们没有引入新方法(将抛出 NPE 如果第二个参数为 null) 到 Optional class?
- 我们现在应该用什么Optional或者Objects?
- 新方法是否使 Objects 比 Optional 更受欢迎,因为它们 将立即抛出 NPE 而不是稍后在代码中的某个地方 喜欢 Optional?
如果我有遗留代码,例如:
String str = null;
String result = str == null ? "other string" : str;
这只是一个方法内部的简单检查。我想使用最新的语言特性重构它。现在想想 Optional.orElse
和 Objects.requireNonNullOrElse
之间的区别,哪个更可取?
result = Optional.ofNullable(str).orElse("other string");
或
result = Objects.requireNonNullOrElse(str,"other string);
重点是:这两个方法签名明显不同:
public static <T> T requireNonNullElse(T obj, T defaultObj)
对比
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
第二种方法的 javadoc 为:
Returns 第一个参数,如果它是非空的,否则 returns 是 supplier.get() 的非空值。
换句话说:它使用您在此处提供给它的供应商。
所以,答案是:在您希望与供应商合作的情况下使用第二个版本;否则,您只需采用采用 "less complicated" 参数的该方法的 "more simple" 版本。
背后的原因:当您在两个选项之间做出决定时,您更喜欢/"less reader surprising" 更容易使用的那个。换句话说:当您可以不用时,为什么要提供供应商。
关于 Optional 的使用 - 请记住它们的 main 目标是用于 return 类型;不是方法参数(请参阅
然后:更新 class 交付的现有方法 "to the field" 几乎总是不行的。您绝对 不 想要更改已经公开并由您的客户使用的内容的语义;假设特定的语义。
Why haven't the JDK developers updated existing methods in Optional class?
因为这会引入一个会破坏许多现有程序的重大更改,并且因为如果需要,该方法应该允许获取 null。
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
可能是因为那样会使 API 更加复杂和臃肿,而没有明显的优势。如果你想确保你的代码不会 return null 意外地,你仍然可以用 requireNonNull 包装结果。
What should we use now Optional or Objects?
如果您需要从可选的 return 方法中提取值,请使用可选的方法。如果要确保满足不应为空的方法参数的前提条件,请使用 Object.requireXxx。 JDK 设计者从来没有提倡使用 Optional 来包装一个值并检查是否为 null。可选的是 return 个值。
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
参见前面的观点:您不使用这些方法来做同样的事情。
Q. Why haven't the JDK developers updated existing methods in Optional class?
一个。因为 Optional
class 是为了避免 NPE 而设计的。
Q. Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
一个。同样的答案。
Q. What should we use now Optional or Objects?.
一个。两个都。 Objects
用于简单的 "not null" 检查,Optional
用于链式操作,如 map
、flatMap
、`filter'。
Q. Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
一个。视情况而定。如果您已经将 Optional 作为某些方法的 return 值,那么最好使用 Optional.
所以要点是您是否喜欢使用 ifs 来检查是否为 null。如果你有一个方法可以接受可以是空值的参数,那么使用 Objects 会更有意义。使用 Optional 的唯一合理的地方是验证对 returns 可选结果的方法的调用。
开发人员希望使用更实用的方法来检查空值,因此为此目的使用结构 Optional.ofNullable
,这不是一个好的做法,因为它会产生垃圾。
您问题的最短答案 "which is preferable?" 一直是开发人员的最爱 "it depends" 因为 Objects::requireNonNullElse
和 Optional
涵盖不同的用例。
两种选择
在回答您的问题之前,我想先介绍一下这两种选择的背景。
Objects::requireNonNullElse
Objects::requireNonNull
确保调用的结果永远不会为空(因此得名)。通常用于简洁地验证构造函数或方法参数,让读者一眼就能验证return赋值的变量不能为null。
所以 Objects::requireNonNullElse
突然允许 null
不仅很奇怪,而且几乎没有用,因为:
// if requireNonNullGet would allow null as second argument,
// the following is true for all x (including null)
Objects.requireNonNullElse(x, null) == x
您可能会争辩说 requireNonNullElseGet
是不同的,因为它可能会调用一个函数,根据某些状态,该函数可能 return null
或不。这是真的,我认为它被考虑过,但是如果这三种情况中的一种实际上允许调用的最终结果是 null
,那么 requireNonNull...
API 会非常奇怪,即使名称说 需要非 null。
Optional
Optional
was designed as a return argument in cases where returning null
is very likely to cause NPEs (like for a Stream
's terminal operation, where it was first used). Although some developers prefer to use it in more cases (compare Stephen Colebourne's pragmatic approach and my strict approach) 没有人真正建议像您的演示那样使用它:
Optional.ofNullable(nullStr).orElse(null);
Optional.ofNullable(nullStr).orElseGet(() -> null);
Optional
是一种在类型系统中表达可能缺少某些东西的方式——它并不意味着可以替代 if
-null
-检查。从这个意义上说,orElse
或 orElseGet
是 Optional
回到可空类型世界的后门,有时 null
正是你想要使用的,如果某些东西不存在,所以他们接受 null
作为参数(或供应商的结果)是有意义的。
您的问题
现在我们可以回答您的问题了:
Why haven't the JDK developers updated existing methods in Optional class?
从概念上讲,这与 Optional
的用途背道而驰。但是,正如其他人所提到的,这将是一个向后不兼容的更改,因为调用 orElse(null)
会突然抛出异常。
Why haven't they introduced a new method (which will thrown NPE if second argument is null) to Optional class?
API 仅在预期对现有代码进行相当大的改进时才会扩展。我在这里看不到。在许多情况下,orElse
获取调用者专门创建的参数作为空可选值的替代项——很少需要进行额外检查来验证它不是 null
。如果确实需要,请致电 orElse(requireNonNull(x))
.
What should we use now Optional or Objects?
如果您有一个变量(无论是本地变量、参数还是字段)并且您想确保它不为空,请使用 Objects
。如果你想要 return 一些东西,这可能是 null 考虑将它包装在 Optional
中。对创建 Optional
(而不是获取一个调用形式)并在同一链的末尾展开它的代码持怀疑态度。
Do new methods make Objects more preferable than Optional since they will throw NPE immediately and not later on somewhere in the code like with Optional?
我现在肯定很清楚,它们涵盖了不同的用例。但让我解决一下 "and not later on somewhere in the code like with Optional":无论您做什么,请确保在您的代码中检查您想要的可空性 属性(可以是 null
,也可以不是)。不要 return 你认为不可能的东西 null
但事实证明是因为你没有检查。如果发生这种情况,那不是 Optional
的错。
If I have a legacy code, something like:
String str = null; String result = str == null ? "other string" : str;
绝对Objects.requireNonNullOrElse(str,"other string");
并考虑使用静态导入使其更具可读性。