Java 8 原始的;空值“;和Java8
我知道处理Java 8 原始的;空值“;和Java8,java-8,optional,Java 8,Optional,我知道处理null原语的最佳实践是使用装箱包装,例如Integer,而不是int,如本文所述 然而,这在今天的Java8中仍然是正确的吗 引入了可选原语,如optionant,其optionant.empty()有效地表示null值?我的理解是,Optionals应该只用于方法返回类型,而不是作为属性本身的类型。“可空”原语是否仍应存储为装箱属性?它们是否应该仅在方法返回类型中是可选的?或者在属性本身中存储为optionant?假设您有一个方法 public void logRequest(I
null
原语的最佳实践是使用装箱包装,例如Integer
,而不是int
,如本文所述
然而,这在今天的Java8中仍然是正确的吗
引入了可选原语,如
optionant
,其optionant.empty()
有效地表示null
值?我的理解是,Optionals应该只用于方法返回类型,而不是作为属性本身的类型。“可空”原语是否仍应存储为装箱属性?它们是否应该仅在方法返回类型中是可选的?或者在属性本身中存储为optionant
?假设您有一个方法
public void logRequest(Integer userID, String content){
//log content locally or in db or a rest call
}
假设您从数据库中为特定用户获取userID
。可能存在以下可能性:
- DB返回一个用户ID
- 找不到id
logRequest
- 是否传递
?如果该方法没有适当的空检查怎么办。它应该推断出什么null
李>null
- 您应该通过
还是0
?如果-1
表示null
,则它可能与ID为0
的实际用户相矛盾。如何区分null和00
public void logRequest(OptionalInt userID, String content)
该方法本身非常清楚地表明,它需要一个可选的参数。因此,只有两种情况需要处理:发送一个适当的参数(这意味着使用0
不能绕过)。如果可选项为空,则方法正确地知道如何处理。(不像以前,我们必须阅读它的文档来预测行为)
因此,它自己的方法声明清楚地说明了行为,而不是为您编写文档并依靠文档和胡乱猜测。在这种情况下,选项非常有用
PS:我总是觉得把
null
传递给一个需要整数的方法有点紧张。感觉绝对不对!天哪,在Java中,潜意识总是把INT当作原语。它们并不意味着为空。在您链接的问题的答案中,解释了原语值为什么不能为null
。没有任何迹象表明使用装箱值表示null
是“最佳实践”,事实上,还没有人说使用null
是一种好的实践
您不应该尝试为基本类型模拟null
值,而应该后退一步,考虑要表达什么。这种语义可以使用多种选项来表达,使用null
不一定是最佳选择之一。表示未初始化或“清除”值的一种简单方法是使用一个额外的boolean fooPropertyInitialized
变量。它比使用null
更清晰,并且它的开销不一定比基本值的装箱更大
这也适用于API。不要对属性使用可选。如果您想支持这样的操作,只需提供一个clearFooProperty()
方法,外加一个isFooPropertyInitialized()
。如果调用方未能首先检查initialized
状态,则让getFooProperty()
抛出异常会更干净
注意,也可以简单地使用对特定上下文有效的范围之外的值来表示特殊条件。这是常见的做法,比如InputStream.read()
方法返回-1
以发送到达末尾的信号
可选
是操作的理想返回类型,而结果没有存储空间,因此无法将查询存在和值拆分为两个方法调用,并且当前值的值范围不受限制
但是,如前所述,如果不知道您想要表达什么样的语义,我们就无法提出建议,而且如果没有“最佳实践”,可能会有不止一种可能的解决方案……您知道使用Optionant
比普通的Integer
有什么优势吗?对于后者,您只需将其分配给null
,并以与optionant
和isEmpty()相同的方式相应地处理它。这是一个有趣的问题。在应用程序的数据模型中,值为“null”的语义是什么?好的,那么每个人所说的语义是什么意思?比如使用0或-1来标记缺少的int值?或者使用了什么业务上下文?“好吧,那么每个人所说的语义是什么意思?”语义(“单词的含义”)是指有一个空的整数
。空表示“空”吗?null仅在某些初始化之前有效吗?null是否表示发生了错误?等等optionant
有一个特定的含义。这是一个非常有趣的答案。有人告诉我,将Optionals作为参数传递给方法不是最优的,应该使用重载。然而,在这样的一些情况下,将可选项作为参数传递语义是有意义的。我认为最好忘记最优性,因为这样的小事情几乎不会影响性能:)。但是,是的,我更喜欢在大多数情况下覆盖,因为它更干净。