问题
这个问题最初是为了找出是否有人知道修改Eclipse equals()和hashCode()模板的方法来为字符串生成以下模式(使null等效于“”)。
if ([value] == null || [value].length() == 0) {
if (other.[value] != null && other.[value].length() > 0) {
return false;
}
} else if (![value].equals(other.[value])) {
return false;
}
一个建议的解决方案
很多答案都建议在setter中标准化输入(将所有空字符串转换为空值,或将空值转换为空字符串)。我发现那很危险。如果用户不知道这种副作用,这里有两段合法的代码会使程序崩溃。
如果所有空字符串都为空,则会崩溃:
myObject.setName("");
String uppercaseName = myObject.getName().toUpperCase();
如果所有空值都成为空字符串,这将会崩溃(辩论的这方面的可行性,我通常希望它可以工作):
myObject.setName(myStringSubclassInstance);
MyStringSubclass string = myObject.getName().someCustomSubclassMethod();
如果我沿着这条路走下去,我会让setter抛出一个InvalidArgumentException并在文档中拼写出来。这是恕我直言的正确方式。
更好的解决方案
最终,我认为任何推荐的解决方案都不合适。这不是他们的错,因为它是原始问题的错误。在考虑反馈之后,我同意原始问题是基于一个不可取的解决方案。我不能删除它,所以我编辑它以避免误导别人。
我决定使用 Builder Pattern 来规范化build()方法中的值。这会导致对象始终具有null或空字符串,但不会对setter或equals()方法添加副作用。
答案 0 :(得分:3)
这可能对您的应用程序有效,但总的来说这并不是一个好主意,特别是对于全局应用的模板。在很多情况下,Null和“”不是一回事 - 例如,如果你认为这两者是相同的,你如何区分未初始化和现有但是空值?
您也可以考虑初始化默认值或使用apache EqualsBuilder
答案 1 :(得分:1)
您的方法的问题是null
,就Java语言而言,空字符串确实是不同的值,甚至String.equals()
方法也将null
和空字符串视为不相等的。因此,您需要使用处理null
情况的比较替换字段的所有String.equals比较。
这会为您提供一些工作,但您的选择包括:
null
,equals
和hashCode
实现,或者第一种可能是最好的方法,特别是如果更进一步,摆脱null
字符串值可能蔓延的其他代码。
答案 2 :(得分:0)
如果您不关心null
vs ""
,那么您可以规范化课程内的值,使其始终为""
。那么你永远不会在equals()
方法中比较空值。