我将此getter/setter编写为Eclipse源代码菜单中的列表:
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
和Sonar报告了两个问题:
返回"date“的副本并存储"date”的副本
有这样的解释
“不应直接存储或返回可变成员”
并给出了示例代码:
public String [] getStrings() {
return strings.clone();}
public void setStrings(String [] strings) {
this.strings = strings.clone();}
我想如果我的Date是空的,它会抛出一个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;
}
}
现在标志着另一个问题:
“将对象赋值为null是一种代码气味。请考虑重构”。
我已经在互联网上搜索,设置或返回一个新的数组对我来说不是一个解决方案,如果setter参数为null,我想保留我的列表为null,以覆盖现有的以前的列表。
对于List,我也遇到了同样的问题,我想为一个空列表返回/保留null,而不是一个新的ArrayList。在本例中,setter标记了另一个问题:
“返回空集合,而不是null。”
这个问题的解决方案是什么?
发布于 2017-02-09 17:34:22
如果您使用的是Java8,并且不想处理空日期,那么使用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);
}
}
代码用法示例:
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()));
尝试更改toto.setMyDate(...)使用具体的日期值来查看发生了什么。
如果你不知道什么是可选的,也不知道如何使用它,你可以找到很多例子。
但:这只是一种解决违规问题的方法,我完全同意布拉德的说法,Optional并不打算用作类型,而更像是一个潜在的空/空返回的契约。通常,如果冲突不正确,您不应该仅仅为了修复冲突而以错误的方式更正代码。在你的情况下,我认为你应该忽略这种违规行为(不幸的是,Sonar的大多数违规行为)
如果你真的想在你的代码中使用Java8和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;
}
}
这边请,
发布于 2017-02-14 19:40:52
一般来说,虽然使用静态分析工具来验证代码是否有价值,但您不应该盲目地修复弹出的每一个警告。您需要分析触发的问题,并检查它是否真的适用于您的上下文。
现在来解决你提到的问题
返回"date“的副本并存储"date”的副本
这似乎是有效的。最好是防御性的,不要通过getter/setter暴露可变状态。因此,应该在getter/setter中创建一个防御性副本。这可以按照您的方式完成,也可以使用新的Java Time API来完成,它提供了不可变的对象。
将对象赋值为null是一种代码味道。考虑重构
这是一个可疑的问题。这个问题是由PMD plugin (分析代码的工具,SonarQube正在显示报告)引起的。这个规则http://pmd.sourceforge.net/pmd-4.3.0/rules/controversial.html#NullAssignment提出了问题,正如您可以看到的,它属于有争议的类别。我不认为您的代码有任何错误,正确的操作可能是忽略此警告,并将问题标记为“无法修复”。您还可以在质量配置文件设置中将SonarQube配置为不使用此特定规则。
返回空集合而不是null。
您没有提供触发它的代码,但这似乎是一条有效的建议。通常,返回空集合比返回null值更好。
发布于 2017-02-09 17:42:43
你不需要在你的setter中明确地设置null
,只需要像这样使用传入的值就可以了。
public void setDate(Date date) {
if (date != null) {
this.date = new Date(date.getTime());
} else {
this.date = date;
}
}
就我个人而言,我永远不会在任何可能的情况下允许空值进入我的值对象,但这只是我固执己见的编码风格。
我对任何人的建议是首选不可变值对象,在这些对象中,您可以在构造函数中设置所有值,并且不允许使用空值。这种风格可能并不适合所有需要java bean getter/setter的第三方库,所以要知道在哪里可以有效地使用它来简化您的代码。
编辑
如果上面的代码仍然给出警告,并且您必须具有“属性尚未设置”功能,则另一种方法是定义一个"null对象“,如下所示
public static final Date NO_DATE = new Date(Long.MIN_VALUE);
public void setDate(Date date) {
this.date = (date == null) ? NO_DATE : new Date(date.getTime());
}
此类的用户可以像这样引用NO_DATE对象,这仍然有利于代码的可读性
if(toto.getDate() != NO_DATE) ...
或者将其封装到另一个方法中,以便像这样使用它
if(toto.hasDate()) ...
当然,与@kij的Java8可选方法相比,这并没有增加太多好处,但它确实适用于任何版本的Java
https://stackoverflow.com/questions/42131930
复制相似问题