3 回答
TA贡献1817条经验 获得超6个赞
我觉得这个问题的前提已经是错误的了。您不应该在大多数地方检查空字符串——事实上,我认为您应该null
尽可能避免使用,尤其是当存在另一个非空标记值时。并且String
已经有了一个很好的“空”值:空字符串 ( ""
)!
如果""
并且" "
需要折叠成相同的值,那么标准库中已经有一个非常好的方法:.trim()
. 但是,.trim()
作为 上的实例方法String
,仅适用于非空字符串。这不一定是坏事!
如果null
和对你来说""
意味着不同的东西,那么我认为你的数据模型太复杂了,你应该使用其他一些包装类而不是String
直接使用。如果null
和""
意思相同,那么您应该选择其中之一,并始终如一地使用它。这可能意味着需要进行一些!= null
检查,但是如果您发现自己在整个代码库中经常需要一个isNullOrEmpty
或isNotBlank
辅助函数,我会说这是一种代码异味,您确实应该致力于修复底层数据模型问题,而不是担心小助手功能。
这意味着什么?在避免!= null
陈述问题中,最高投票的答案指出,实际上只有两种值可以为 null:(1) null 是有效值,或 (2) null 不是有效值.
情况(2)不是很有趣。Null 不是有效值,因此我们不应该尝试处理它。如果有的话,我们只要遇到它就抛出一个异常。否则我们会忽略它,让NullPointerException
事情“自然地”发生。它不应该为空,因此根据定义,找到空值是一种特殊情况。
如果 null是有效值,则表示 null 具有语义含义。这很可能意味着某个值“不存在”或“无效”。这里有两种子情况:(1a) null 表示与空字符串相同的内容,或 (1b) 表示不同的内容。
如果您有案例 (1b),那么我认为您的域模型中需要一个新实体。例如,您可以创建一个类似的类PaymentTerm
,它具有单独的.isValid()
和.isPresent()
方法,以及一个.asString()
访问器来获取字符串值(如果存在)。(在很多可能的方式,使一个PaymentTerm
类,有很多可能的权衡:点是不是你需要这种特殊形式,但你需要的东西多了原始String
的东西,你可以挂方式关闭的,因为这个东西现在是你的领域模型中的一流实体。)
如果您有 case (1a),那么 null 和空字符串在语义上都意味着相同的事情。但是它们在语法上非常不同!空字符串已经有一个实例方法来检查它 ( .isEmpty()
) 并且可以安全地存储、传递、与其他字符串进行比较等。
因此,情况 (1a) 有两种可能的解决方案:(1a.1) 传递 null 和空字符串,并且在任何地方都必须检查其中之一,或者 (1a.2) 尽快将空值标准化为空字符串,然后将 null 视为无效值,并在任何地方使用空字符串。根据您的输入格式,您甚至可以“免费”获得这种行为(例如,空文本框自然将空字符串作为值,而不是空值)。
我的论点是 case (1a.1) 是一种代码异味。与其同时传递 null 和空字符串,并经常检查两者(手动或使用类似isNullOrEmpty
或的方法isNotBlank
),您应该尝试进入 case (2) 或 case (1a.2)。
请注意,这其实答案意味着,两个 isNotBlank
和!= null
是次优!在分解良好的代码库中,您应该努力避免这两种情况,但我倾向于认为您应该努力避免isNotBlank
更多类似的情况。
也就是说,如何检查 null 或空字符串并不是非常重要。无论如何,JIT 几乎肯定会内联检查,并且在许多情况下,如果窥视孔优化器可以以另一种方式证明空安全,则会完全忽略它们。要考虑的更重要的事情是null
您的程序中是否为有效值,如果是,则值为空在语义上意味着什么。
TA贡献1877条经验 获得超6个赞
你的问题是有道理的,但你问问题的方式可以更有礼貌。
答案是,这取决于。StringUtils 提供了很多不错的方法。isNotBlank() 检查空、空以及一个或多个空白,并且节省了一定量的手动检查。它还可以简化单元测试。另一方面,您的商店可能不想导入并依赖外部库。
一般来说,正确的方法,尤其是当你刚开始的时候,是一样的。礼貌地询问技术负责人的意见,然后接受。
TA贡献1876条经验 获得超7个赞
paymentTerm != null
并且StringUtils.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"))
添加回答
举报