StringUtils vs!=空

时间:2018-09-10 18:06:09

标签: java string validation nullpointerexception

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

3 个答案:

答案 0 :(得分:2)

我觉得这个问题的前提已经是一个不正确的问题。您不必在大多数地方检查空字符串-实际上,我认为您应该尽可能避免使用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类的很多可能方法,但有很多可能的折衷:并不是说您需要这种特定的形式,而是需要更多的 something 原始String,您可以将其挂起方法,因为这已经成为您域模型中的一流实体。)

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

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

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

请注意,此答案实际上意味着两者 isNotBlank!= null都不是最佳选择!在结构良好的代码库中,您应该努力避免它们两者都出现,但是我倾向于认为您应该在工作时更加避免使用类似isNotBlank之类的东西。

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

答案 1 :(得分:0)

paymentTerm != nullStringUtils.isNotBlank(paymentTerm)执行的功能不同。
如果只想检查String对象的非无效性,则不想使用isNotBlank(),而要使用!= null。因此,使用!= null仍然有意义。
请注意,您也可以使用Object.nonNull(Object),但它通常更冗长(但在方法参考中,它完全有意义:Object::nonNull)。

关于我们应该测试!= ""!= trimmed ""还是仅仅测试!= null之后,这是必须要做的事情。
即使isNotBlank()包含!= null,您也只能按必需的要求使用它,因为执行更多所需的检查会误导代码。


这里有一些简单的示例,您可以看到每种方式都有其含义,而您必须以某种方式使用它们(或不使用它们),以使它们的阅读自然而愉悦。

1)您要检查String的长度大小。

if (myString != null && myString.length() == 8)

正是您需要的。
isNotBlank()来做是很冗长的,它传达了两个非常具体的内容(不是空白和最小长度),而只有最后一个很重要。

if (StringUtils.isNotBlank(myString) && myString.length() == 8)

2)您要检查String是否包含某些字符。

if (myString != null && myString.contains("word"))

仍然是您需要的。

if (String.isNotBlank(myString) && myString.contains("word"))  

使用isNotBlank()进行操作似乎仍然是杂音。

3)您要检查String是否等于另一个不能为null或为编译时常量表达式的值。

您想直接写:

if ("word".equals(myString))

4)那么您什么时候要使用isNotBlank()
仅当您需要检查String是否不为并且并且不仅包含空格(" ")字符时。

if (StringUtils.isNotBlank("word"))

答案 2 :(得分:0)

您的问题是有效的,但您可能会问得更礼貌。

答案是,这取决于。 StringUtils提供了许多不错的方法。 isNotBlank()检查null,empty和一个或多个空格,并节省一定数量的手动检查。它还可以简化单元测试。另一方面,您的商店可能不想导入并依赖外部库。

通常,正确的方法(尤其是刚入门时)是相同的方法。礼貌地向技术负责人征询他们的意见,然后接受。