2010-09-11 26 views
1

问题
这个问题本来是找出是否有人的方式知道修改了Eclipse的equals()和hashCode()模板来生成以下模式用于字符串(使null等于“”)。Eclipse的equals()方法的模板了空字符串==空字符串

if ([value] == null || [value].length() == 0) { 
    if (other.[value] != null && other.[value].length() > 0) { 
     return false; 
    } 
} else if (![value].equals(other.[value])) { 
    return false; 
} 

提出的一种解决方案
很多答案都建议正火输入在设置器(无论是将所有空字符串空值,或空值为空字符串)。我觉得这很危险。这里有两个合法的代码片断,如果用户不知道这种副作用,它会使程序崩溃。

如果所有的空字符串由空值,这将崩溃:

myObject.setName(""); 
String uppercaseName = myObject.getName().toUpperCase(); 

如果所有空值由空字符串,这将崩溃(辩论的这个可取之外,我一般会期望它的工作):

myObject.setName(myStringSubclassInstance); 
MyStringSubclass string = myObject.getName().someCustomSubclassMethod(); 

如果我去了这条道路,我会做的setter将引发InvalidArgumentException和拼写出来的文档。这是恕我直言的正确方法。

更好的解决方案
最终,我不认为任何推荐的解决方案是合适的。这不是他们的错,因为这是原始问题的错。在考虑反馈意见后,我同意最初的问题是基于一种不可取的解决方案。我不能删除它,所以我编辑它以避免误导他人。

我决定去使用Builder Pattern来规范build()方法中的值。这会导致对象始终具有null或空字符串,但不会为setter或equals()方法添加副作用。

+1

存在'String#isEmpty()'。顺便说一句:这是老实说,一个可怕的想法。您需要以不同的方式解决空字符串问题。 – BalusC 2010-09-11 03:17:00

+0

@BalusC我不是纯粹主义者。等价是主观的,在这种情况下,我选择将String属性的等价定义为!null &&!empty && equal或null ||空。我意识到我的应用程序中这些对象的用例,并为我的目的一个空==“”。我知道,我可以修改所有的setter来放弃空字符串或其他东西,但我认为这没什么更好的。 – DougW 2010-09-11 03:41:15

回答

3

这可能适用于您的应用程序,但总的来说这并不是一个好主意,尤其是对于全局应用模板。在很多情况下,空值和“”不是同一个东西 - 例如,如果你认为这两者是相同的,那么你如何区分未初始化的值和现有的空值?

你也可以考虑初始化缺省值或使用Apache EqualsBuilder

+0

是的,我不想将它应用到任何地方。只在选择的类中。我会明天检查EqualsBuilder,看看它是否适用于我。 – DougW 2010-09-11 03:30:21

1

与方法的问题是null和空字符串真的是不同的值就Java语言而言,甚至String.equals()方法治疗null和一个空字符串不相等。因此,您需要用处理null大小写的比较替换字段的所有String.equals比较。

此向您提供一些工作,但你的选项包括:

  • 写你的类,以便领域是从来没有null
  • 写自己的equalshashCode实现的类,或
  • 为Strings编写自己的包装类。

第一个可能是最好的办法,特别是如果采取这一步,摆脱其他代码,其中null字符串值可以在蠕动。

+0

@Stephen C我实际上认为第一种选择更危险。你必须重写setter函数来为null(烦人)抛出一个异常,或者为空值设置一个空字符串(意外的,潜在的危险)。我们可以进入构建器模式等,但我真正想要的只是选项#2的模板引擎。 #3将是非常危险的,因为这些字符串可能会传递到其他地方,不期望的功能。 – DougW 2010-09-12 19:55:35

+0

@DougW - 如果你的应用程序设计说'null'和'“”'意味着同样的事情,那么你应该*对待它们并且在setter中对它们进行规范化。这并不危险。它只是简单地实现你的设计。就希望模板引擎为您完成工作而言,Eclipse不会实现此AFAIK。你可能想反思为什么不。我的理论是他们(会)认为这是错误的方法。 – 2010-09-12 21:46:59

+0

@Stephen C - 我很欣赏你的观点。我不认为Eclipse不包括某些东西很适合它。我只是没有把安全套中的空值转换为空字符串的安全性。如果有人设置了一个房产,他们希望这是他们刚刚设定的。从对象比较的角度来看,它恰好是等价的。 – DougW 2010-09-12 22:49:21

0

那么,如果你不关心null VS "",你可以规范你的班级里的价值,所以他们总是""。然后,您将永远无法比较equals()方法中的空值。

+0

同意。但问题是如何?写入setter,抛出invalidargument异常,或拦截null并将它们转换为空字符串(baaaad idea)?抛出异常会没问题,但是我自动生成代码时遇到了同样的问题。而且我还根据模板引擎的可用性做出了设计决策,这让我感到畏缩。 – DougW 2010-09-12 20:00:20

+0

我不明白为什么在你的类里面把'null'转换成'“”'“(或者相反)是一个坏主意。毕竟,在这种情况下,他们和你是平等的。 – gpeche 2010-09-12 20:30:29

+0

@gepeche我不能在这里添加可读代码,所以我会在我的问题中添加一个编辑来解释为什么这很危险。 – DougW 2010-09-12 22:51:45