24

考虑这一行:

if (object.getAttribute("someAttr").equals("true")) { // ....

显然这条线是一个潜在的错误,属性可能是null,我们会得到一个NullPointerException. 因此,我们需要将其重构为以下两种选择之一:

第一个选项:

if ("true".equals(object.getAttribute("someAttr"))) { // ....

第二种选择:

String attr = object.getAttribute("someAttr");
if (attr != null) {
    if (attr.equals("true")) { // ....

第一个选项阅读起来很尴尬,但更简洁,而第二个选项意图明确,但冗长。

就可读性而言,您更喜欢哪个选项?

4

9 回答 9

27

我一直用

if ("true".equals(object.getAttribute("someAttr"))) { // ....

因为虽然它读起来有点困难,但它不那么冗长,而且我认为它足够可读,所以你很容易习惯它

于 2009-06-08T08:51:55.400 回答
18

在第二个选项中,您可以利用 short-circuiting &&

String attr = object.getAttribute("someAttr");
if (attr != null && attr.equals("true")) { // ....
于 2009-06-08T08:55:45.673 回答
2

在某些情况下,简洁的方法开始时感觉不对,但实际上变得惯用了。这是其中之一;另一个是这样的:

String line;
while ((line = bufferedReader.readLine()) != null) {
  // Use line
}

在某种情况下的副作用?不可思议!除了当您识别特定模式时,它基本上比替代品更好。

这种模式很相似——它在 Java 中很常见,我希望任何有经验的开发人员都能认出它。结果非常简洁。(有趣的是,我有时会看到 C# 代码不必要地使用相同的习语 - 相等运算符在 C# 中可以很好地处理字符串。)

底线:使用第一个版本,并熟悉它。

于 2009-06-08T09:02:57.077 回答
1

我喜欢选项 1,我认为它足够可读。

选项 3 顺便说一句,将引入一个 getAttribute 方法,该方法将默认值作为参数。

于 2009-06-08T08:53:05.427 回答
1

总是渴望更短的代码,因为两者在功能上是等效的。尤其是在这种不牺牲可读性的情况下。

于 2009-06-08T08:56:58.337 回答
0

Util.isEmpty(string)-如果是,则string == null || string.trim().isEmpty() Util.notNull(string)返回 "" string == null,否则返回字符串。 Util.isNotEmpty(string)回报!Util.isEmpty(string)

我们有一个约定,对于字符串,Util.isEmpty(string)语义上意味着真,Util.isNotEmpty(string)语义上意味着假。

于 2009-06-08T08:55:23.207 回答
0

这是一个很好的问题。我通常使用不优雅:

if (object.getAttribute("someAttr") != null && object.getAttribute("someAttr").equals("true")) { // ....

(我不会再使用它了)

于 2009-06-08T09:03:37.387 回答
0

我有另一个答案;

List<Map<String, Object>> group = jjDatabase.separateRow(db.Select("SELECT * FROM access_user_group  WHERE user_id=1 ;"));

我的数据库中的“access_user_group”中没有“group_c80”作为列,因此在 get(0).get("group_c80") 中符合空指针异常。但我通过下面的代码处理它:

for (int j = 1; j < 100; j++) {
                    String rulId="0";//defult value,to privent null pointer exeption in group_c
                    try {
                        rulId = group.get(0).get("group_c" + j)).toString();
                    } catch (Exception ex) {
                        ServerLog.Print( "Handeled error in database for " + "group_c" + (j < 10 ? "0" + j : j) +"This error handeled and mot efect in program");
                        rulId = "0";
                    }}
于 2015-03-05T18:33:33.353 回答
0

这是我的方法,PropertyUtil虽然需要一个类,但它只写一次:

/**
 * Generic method to encapsulate type casting and preventing nullPointers.
 * 
 * @param <T>          The Type expected from the result value.
 * @param o            The object to cast.
 * @param typedDefault The default value, should be of Type T.
 * 
 * @return Type casted o, of default.
 */
public static <T> T getOrDefault (Object o, T typedDefault) {
    if (null == o) {
        return typedDefault;
    }
    return (T) o;
}

客户端代码可以这样做:

PropertyUtil.getOrDefault(obj.getAttribute("someAttr"), "").equals("true");

或者,对于列表:

PropertyUtil.getOrDefault(
    genericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST
).contains(element);

或者对于 List 的消费者,它会拒绝 Object:

consumeOnlyList(
    PropertyUtil.getOrDefault(
        enericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST
    )
)

默认值可能是空对象模式https://en.wikipedia.org/wiki/Null_Object_pattern的 impl

于 2016-04-29T15:31:49.543 回答