使用Date或List在简单的getter和setter方法中解决Sonar问题

Jav*_*i L 7 java getter-setter sonarqube

我将这个getter/setter写成Eclipse源菜单中的列表:

public Date getDate() {
    return date;
}

public void setDate(Date date) {
    this.date = date;
}
Run Code Online (Sandbox Code Playgroud)

和Sonar报告了两个问题:

返回"日期"的副本并存储"日期"的副本

随着解释

"不应存储或直接退回可变成员"

和一个示例代码:

public String [] getStrings() {
    return strings.clone();}

public void setStrings(String [] strings) {
    this.strings = strings.clone();}
Run Code Online (Sandbox Code Playgroud)

我想如果我的Date为null,它将抛出NullPointerException.然后我将我的代码更改为:

public Date getDate() {
    if (this.date != null) {
        return new Date(this.date.getTime());
    } else {
        return null;
    }
}

public void setDate(Date date) {
    if (date != null) {
        this.date = new Date(date.getTime());
    } else {
        this.date = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在标志着其他问题:

"将对象分配给null是一种代码气味.考虑重构".

我在互联网上搜索并设置或返回一个新数组对我来说不是一个解决方案,如果setter param为null以覆盖现有的前一个列表,我想保留我的列表为null.

我对List有同样的问题,我想为空List返回/保留null而不是新的ArrayList.在这种情况下,setter标记了另一个问题:

"返回一个空集合而不是null."

这个问题的解决方案是什么?

kij*_*kij 3

如果您使用 Java 8 并且不想处理空日期,那么也许使用Optional会对您有所帮助。

编辑:“POJO”类的示例

public class Toto {

    public Optional<Date> myDate;

    public Optional<Date> getMyDate() {
        return this.myDate;
    }

    public void setMyDate(final Date myDate) {
        this.myDate = Optional.ofNullable(myDate);
    }

}
Run Code Online (Sandbox Code Playgroud)

代码使用示例:

Toto toto = new Toto();
toto.setMyDate(null);
System.out.println("Value is null ? " + toto.getMyDate().isPresent());
System.out.println("Value: " + toto.getMyDate().orElse(new Date()));
Run Code Online (Sandbox Code Playgroud)

尝试使用具体日期值更改 toto.setMyDate(...) 看看会发生什么。

如果您不知道什么是可选或如何使用它,您可以找到很多示例。

但是:这只是解决您的违规问题的一种方法,我完全同意 Brad 的评论,Optional 无意用作类型,而更像是潜在的空/空返回的合同。一般来说,如果违规行为不正确,您不应该仅仅为了修复违规行为而以错误的方式更正代码。在你的情况下,我认为你应该忽略违规行为(不幸的是,声纳的大多数违规行为都是如此)

如果你真的想在你的代码中使用 Java 8 和Optional,那么你的 POJO 类将是这样的(仅使用Optional作为getter的对照)

public class Toto {


    public Date myDate;

    public Optional<Date> getMyDate() {
        return Optional.ofNullable(this.myDate);
    }

    public void setMyDate(final Date myDate) {
        this.myDate = myDate;
    }

}
Run Code Online (Sandbox Code Playgroud)

这边走,

  • 你的bean保持可序列化(可选不是)
  • 您仍然可以让“客户端”代码选择如何处理属性的空/空值
  • 将您的声纳违规配置为误报,因为这正是您想要的,而不是更改代码

  • 以这种方式使用“Optional”并不是该语言的意图。引入它是为了支持 java.util.Streams API。任何使用“Toto”类的代码仍然必须通过调用 isPresent() 来处理“null”检查,那么好处在哪里呢?真正的解决方案是如果可能的话,首先不允许空值进入类。 (2认同)