避免大量的!= null检查bean属性

时间:2012-10-11 08:01:22

标签: java nullable

考虑我有以下豆子:

@Entity
public class Currency {

    private String currency;

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }
}

@Entity
public class SomeEntity  {
    private Currency currency;

    public Currency getCurrency() {
        return currency;
    }

    public void setCurrency(Currency currency) {
        this.currency = currency;
    }
}

我有SomeEntity的实例:

SomeEntity entity;

在代码中的某个地方,我想使用某个实体的属性,但实体可能是null,而实体的某些属性可能是null,所以我当前的代码实现远非易事 - 阅读的:

new ConstantExpression(entity == null ? null : entity.getCurrency() != null ? entity.getCurrency().getId() : null)

是否有任何方法可以提高此案例的代码可读性?

更新:我的代码库足够大,因此Null object pattern实现需要进行大量修改。另外,我的bean通过JPA持久保存到db,所以我将不得不像Cascade注释那样进行额外的编码等等。

4 个答案:

答案 0 :(得分:1)

您可以使用Null Object Pattern

  • 创建货币的子类,其中getId()始终返回null
  • 拥有此类的一个实例,用于初始化所有currency字段。
  • 现在getCurrency().getId()是安全的。
  • 如果您愿意,请对SomeEntity
  • 重复相同的操作

答案 1 :(得分:1)

由于语言的设计方式,我们永远不会完全没有空检查。但是当他们觉得太烦人时,我喜欢做的一件事。

创建一个“utils”类,为您执行空检查。一旦我在公共场所找到StringUtils,那就是一个“aha”时刻。想象一下,你有两个字符串需要比较相等。

String a;
String b;
// code goes here. a and/or b may or may not be initialized

if (a.equals(b))
{
    // do something
}

正如您痛苦地意识到的那样,上面的代码存在NullPointerException的风险。所以我们必须写:

if (a != null && a.equals(b))
{
    // do something
}

输入StringUtils。相反,我们写

if (StringUtils.equals(a,b))
{
    // do something
}

如果这太冗长,或者我在这段代码中做了很多等号,我们可以使用静态导入:

import static org.apache.commons.lang.StringUtils.*;
//...

if (equals(a,b))
{
    // do something
}

Voila - 即时简洁的代码。这魔术是如何实现的?没有魔法,只需将空检查放在静态方法中。这是StringUtils的实现:

public static boolean equals(CharSequence cs1, CharSequence cs2) {
    if (cs1 == cs2) {
        return true;
    }
    if (cs1 == null || cs2 == null) {
        return false;
    }
    if (cs1 instanceof String && cs2 instanceof String) {
        return cs1.equals(cs2);
    }
    return CharSequenceUtils.regionMatches(cs1, false, 0, cs2, 0, Math.max(cs1.length(), cs2.length()));
}

在你的情况下,考虑编写一个这样的utils类:

public class MyUtils
{
   public static String getCurrencyId(Currency currency)
   {
      if (currency == null)
         return null;
      return currency.getId();
   }

   public static String getCurrencyId(SomeEntity entity)
   {
      if (entity == null)
         return null;
      return getCurrencyId(entity.getCurrency())
   }
}

现在在调用代码中只需执行

import static mypackage.MyUtils.*;

new ConstantExpression(getCurrencyId(entity));

是的 - 使用这样的课程是妥协。首先必须创建课程是令人讨厌的,只有你可以决定是否值得付出努力。但是,如果调用代码非常复杂并且空检查实际上使得难以遵循逻辑,那么从长远来看,拥有一个单独的utils类来隐藏空检查可能会更省力。

答案 2 :(得分:0)

你可以简单地实现一个装饰器,它接受一个实体并简单地提供方便的访问方法。

答案 3 :(得分:0)

虽然我不喜欢使用它们,但有些人使用“Null”对象,这些对象充满了“Null”值和对象,而不是null