我的代码从DB读取一些配置值。如果它们未定义(由getValueFromDB方法返回null)我想将它们默认为配置文件中定义的值。
可以使用Optional.ofNullable()。OrElse()对所有出现的getValueFromDB()进行空检查,并在null的情况下分配默认值。 或者这是滥用/滥用Optional?
答案 0 :(得分:4)
好吧,我们在我们的代码库中使用这个成语就像疯了一样 - 我认为没有任何问题。这就是Optional
对我而言的所有内容 - 如果某些价值存在与否,则强迫您采取行动;我非常喜欢的是它是用java-8构建的语言本身,我不必为此引入其他方法(或像guava
这样的库。)
你可能会考虑这个简单的例子,但Optional
显然有其他链式方法,所以我可以这样做:
Optional.ofNullalbe(dbPass)
.map(// do mapping)
.filter(// do filtering)
.ifPresent(x -> // log it )
使用其他方法无法轻松实现这一目标。
答案 1 :(得分:1)
这似乎是一种小小的虐待,但我对此并不十分强烈。也许如果有足够的程序员开始这样做,它将成为公认的成语。
但是你可以在不使用Optional
的情况下做同样的事情:
public static <T> T useValueOrDefault(T value, T defaultValue) {
return (value == null) ? defaultValue : value;
}
并在任何地方使用此方法而不是Optional.ofNullable(value).orElse(default)
。 (注意:未经过测试)
我确实发现实现此功能的内置构造,如Javascript中的||
或Kotlin中的?:
,都很有用。太糟糕的Java没有等价物(编辑:根据@ Holger的评论,Java 9引入了一个)。
答案 2 :(得分:0)
以相同的方法使用Optional
将某事物转换为orElse
只是立即 将其转换回包装类型感觉过于华丽。
对我来说,Optional
的更多内容是在方法的类型签名中公开返回值可能为空的可能性。 Optional
类型通知使用者它可能为空。如果您在上一行代码中使用ofNullable
创建了它,那么您既是创建者又是消费者,并且已经知道它可能是null
,因此就地处理它而不用创建一个新的短暂对象。
但是,Optional
会产生整洁的代码,而我的第一个直觉是询问您的数据库API是否具有返回Optional.empty()
而不是返回null
本身的能力。这取决于您使用的库,到2020年的可能性可能比您在2017年提出问题时的可能性高。
在那种情况下,如果这是应用程序逻辑,那么使用returnedOptional.orElse(default)
是很有意义的。
如果您的数据库API无法给您Optional
,在应用程序逻辑中,我不会通过Optional
进行默认设置。使用起来更简单明了:
return value == null ? default : value;
但是,我会考虑在您的不支持Optional的数据库API和应用程序逻辑之间添加一个薄的抽象层,在适当的情况下只做Optional.ofNullable()
。 他们的数据库库没有所需的API,因此请将其包装以创建所需的API。 您的数据库库对调用者有礼貌,即当值不存在时,类型签名应如此。
所以代替:
MyType maybeS = theirDbLibrary.query(...);
MyType s = (maybeS == null) ? default : maybeS;
您将拥有:
Optional<MyType> maybeS = myWrappedDbLibrary.query(...);
MyType s = maybeS.orElse(default);
此处的目的是从您的应用程序逻辑中删除null
的所有知识。如果您应用程序的核心根本没有引用null
(包括ofNullable
),那确实很棒。它消除了很多错误的机会。但是为此,您需要消除将null
传递到您的代码中的可能性-这就是数据库和应用程序代码之间的清理层在其中工作的地方。