java - StringUtils vs!=空

标签 java string validation nullpointerexception

我经常遇到非常不同的String验证,并且我们都知道有新的库,例如StringUtils。有人可以解释为什么StringUtils.isNotBlank(paymentTerm)paymentTerm != null或多或少受到青睐吗?

最佳答案

我觉得这个问题的前提已经是一个不正确的问题。您不必在大多数地方检查空字符串-实际上,我认为您应该尽可能避免使用null,特别是当存在另一个非空哨兵值时。而且String已经有一个很好的“空”值:空字符串("")!

如果""" "需要折叠为相同的值,则标准库中已经存在一个非常好的方法:.trim()。但是,.trim()作为String的实例方法,仅适用于非空字符串。这不一定是一件坏事!

如果null""对您来说意味着不同,那么我认为您的数据模型太复杂了,您应该使用其他包装类而不是直接使用String。如果null""表示相同的内容,则应选择一个或另一个,并始终使用它。这可能意味着需要进行一些!= null检查,但是如果您发现自己在整个代码库中经常需要isNullOrEmptyisNotBlank辅助函数,我会说这是一种代码味道,您确实应该努力修复潜在的数据模型问题,而不用担心很小的辅助函数。

这意味着什么?在Avoiding != null statements问题中,投票最高的答案指出,实际上只有两种实例的值可以为null:(1)null是有效值,或者(2)null不是有效值值。

情况(2)不是很有趣。 Null不是有效值,因此我们不应该尝试处理它。如果有的话,如果遇到异常,我们只是抛出一个异常。否则,我们将忽略它,并让NullPointerException自然发生。它不应该为null,因此按定义查找null是一种例外情况。

如果null为有效值,则表示null具有语义。最有可能意味着值“不存在”或“无效”。这里有两种情况:(1a)null表示与空字符串相同,或者(1b)表示不同。

如果您有案例(1b),那么我认为您需要在域模型中使用新实体。例如,您可以创建一个类似PaymentTerm的类,该类具有单独的.isValid().isPresent()方法,以及一个.asString()访问器以获取字符串值(如果存在)。 (创建PaymentTerm类的很多可能方法,还有很多可能的折衷:重点不是您需要这种特定形式,而是需要除原始String之外的其他东西,您可以可以使用hang方法,因为这是您域模型中的一流实体。)

如果您遇到大小写(1a),则从语义上讲,null和空字符串都意味着同一件事。但是它们在语法上有很大的不同!空字符串已经具有用于检查它的实例方法(.isEmpty()),并且可以安全地存储,传递,与其他字符串相比,等等。

因此,情况(1a)有两种可能的解决方案:(1a.1)您同时传递null和空字符串,并且到处都需要检查其中一个,或者(1a.2)尽快将null归一化为空字符串,然后将null视为无效值,并在所有位置使用空字符串。根据您的输入格式,您甚至可以“免费”获得此行为(例如,一个空文本框自然会将空字符串作为值,而不是null)。

我的论点是案例(1a.1)是一种代码异味。您应该尝试进入大小写(2)或大小写(1a.2),而不是同时传递null和空字符串,并经常检查二者(手动或使用诸如isNullOrEmptyisNotBlank之类的方法), 。

请注意,此答案实际上暗示isNotBlank!= null都不是最优的!在结构良好的代码库中,您应该努力避免它们两者都出现,但是我倾向于认为您应该更努力避免像isNotBlank这样的事情。

也就是说,如何检查null或空字符串并不十分重要。 JIT几乎肯定会以任何方式内联检查,并且在许多情况下,如果窥孔优化器可以通过另一种方式证明空安全性,它将完全消除它们。要考虑的更重要的事情是null在您的程序中是否为有效值,如果是,则在语义上将值设为空意味着什么。

关于java - StringUtils vs!=空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52263237/

相关文章:

java - Android java.lang.NoSuchMethodError

java - 使用java中的客户端id和 key 与oauth2 google api进行连接

c - 当反向字符串的函数返回地址时,我无法打印元素

c++ - 将数据字符串标记为结构 vector ?

mysql - 在 Mysql 中验证电子邮件地址

javascript - 我希望能够使用模板在指令内设置 Angularjs ng-pattern 以及它自己的范围来验证表单

java - Spring Integration Java DSL 如何使用 Spel 进行服务激活器

java - 如何使用 log4j 编写多级日志消息? (例如信息和错误)

java - 如何从文本文件的一行中删除两个字符之间的空格

c++ - 检查有效输入 C++