java 使用 Date 或 List 在简单的 getter 和 setter 方法中解决声纳问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42131930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Solve Sonar issue in simple getter and setter methods with Date or List
提问by Corporativo
I write this getter/setter to list from Eclipse source menu:
我编写了这个 getter/setter 以从 Eclipse 源菜单中列出:
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
And Sonar reporting two issues:
和声纳报告两个问题:
Return a copy of "date" & Store a copy of "date"
返回“日期”的副本并存储“日期”的副本
with the explanation
与解释
"Mutable members should not be stored or returned directly"
“不应直接存储或返回可变成员”
and a example code:
和示例代码:
public String [] getStrings() {
return strings.clone();}
public void setStrings(String [] strings) {
this.strings = strings.clone();}
I think if my Date is null, it will throw a NullPointerException. Then I've changed my code to:
我想如果我的日期为空,它会抛出一个 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;
}
}
And now marks other issue:
现在标记其他问题:
"Assigning an Object to null is a code smell. Consider refactoring".
“将对象分配给 null 是一种代码味道。考虑重构”。
I've searched in internet and set or return a new array is not a solution for me, I want to preserve my list to null if the setter param is null to overwrite an existing previous list.
我在互联网上搜索过并设置或返回一个新数组对我来说不是一个解决方案,如果 setter 参数为空以覆盖现有的先前列表,我想将我的列表保留为空。
I've the same problem for List, and I want to return/preserve null instead of a new ArrayList for an empty List. And in this case, the setter marks one more issue:
我对 List 有同样的问题,我想为空列表返回/保留 null 而不是新的 ArrayList。在这种情况下,setter 标记了另一个问题:
"Return an empty collection instead of null.".
“返回一个空集合而不是 null。”。
What is the solution for this issue?
这个问题的解决方案是什么?
采纳答案by kij
If you are in Java 8 and do not want to handle empty date, then maybe usage of Optional would help you.
如果您使用的是 Java 8 并且不想处理空日期,那么使用 Optional 可能会对您有所帮助。
Edit: Example of your "POJO" class
编辑:您的“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);
}
}
Example of code usage:
代码使用示例:
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()));
Try to change the toto.setMyDate(...) with concrete date value to see what happen.
尝试使用具体日期值更改 toto.setMyDate(...) 以查看会发生什么。
If you don't know what is Optional or how to use it, you can find plenty of examples.
如果您不知道什么是 Optional 或如何使用它,您可以找到大量示例。
BUT: This is only a way to solve your violation issue and i totally agree with Brad's remark, Optional are not intent to be used as a type, but more like a contract for potential empty / null returns. In general, you should not correct your code in a bad way just to fix a violation, if the violation is not correct. And in your case i think you should just ignore the violation (as most of Sonar's one unfortunatly)
但是:这只是解决您的违规问题的一种方法,我完全同意 Brad 的评论,Optional 无意用作类型,而更像是潜在的空/空返回的合同。一般来说,如果违规不正确,您不应该为了修复违规而以错误的方式更正您的代码。在你的情况下,我认为你应该忽略违规行为(不幸的是,大多数声纳都是如此)
If you really want to use Java 8 and Optional in your code, then you POJO class would be like this (usage of Optional as a contrat on the getter only)
如果你真的想在你的代码中使用 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;
}
}
This way,
这条路,
- You bean stay serializable (Optional is not)
- You still enable your "client" code to have the choice on how to behave to empty / null value of your property
- Configure your Sonar violation as a false positive as it is what you want instead of changing your code
- 你 bean 保持可序列化(可选不是)
- 您仍然可以让您的“客户端”代码选择如何处理您的财产的空值/空值
- 将您的声纳违规配置为误报,因为它是您想要的,而不是更改您的代码
回答by Brad
You don't have to explcitly set null
in your setter, just use the value being passed in like this...
你不必null
在你的 setter 中明确设置,只需使用传入的值,就像这样......
public void setDate(Date date) {
if (date != null) {
this.date = new Date(date.getTime());
} else {
this.date = date;
}
}
Personally I would never allow null values into my Value objects where ever possible, but that is just my opinionated coding style.
就个人而言,我永远不会在任何可能的情况下允许空值进入我的 Value 对象,但这只是我自以为是的编码风格。
My advice to anyone is to prefer immutable value objects where you set all the values in the constructor and don't allow nulls in. This style may not be appropriate for all 3rd party libraries that expect the java bean getter/setters so be aware where it can be used effectively to simplify your code.
我对任何人的建议是更喜欢不可变的值对象,你在构造函数中设置所有值并且不允许空值。这种风格可能不适合所有需要 java bean getter/setter 的 3rd 方库,所以要注意在哪里它可以有效地用于简化您的代码。
Edit
编辑
If the above code still gives you the warning and you must have the "property is not set yet" functionality, another approach is to define a "null object" like this
如果上面的代码仍然给你警告,你必须有“属性尚未设置”功能,另一种方法是定义一个“空对象”这样的
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());
}
Users of this class can refer to the NO_DATE object like this, which still makes for readable code
此类的用户可以像这样引用 NO_DATE 对象,这仍然使代码可读
if(toto.getDate() != NO_DATE) ...
Or encapsulate this into another method so it's used like this
或者把它封装成另一种方法,这样使用
if(toto.hasDate()) ...
Of course this doens't add much benefit over the Java 8 Optional approach from @kij but it does work with any version of Java
当然,与@kij 的 Java 8 Optional 方法相比,这并没有增加太多好处,但它确实适用于任何版本的 Java
回答by Tibor Blenessy
Generally, while using static analysis tools to verify the code is valuable, you should not blindly fix every warnings which popups on you. You need to analyze the issue which is triggered and check if it really applies in your context.
通常,在使用静态分析工具验证代码是否有价值的同时,您不应该盲目地修复每个弹出的警告。您需要分析触发的问题并检查它是否真的适用于您的上下文。
Now to address the issues you are mentioning
现在解决您提到的问题
Return a copy of "date" & Store a copy of "date"
返回“日期”的副本并存储“日期”的副本
This seems to be valid one. It is good practice to be defensive and not expose mutable state via getters/setters. So creating a defensive copy in getter/setter should be done. This can be done the way you did it, or by using new Java Time API, which provides immutable objects.
这似乎是有效的。保持防御性并且不通过 getter/setter 暴露可变状态是一种很好的做法。所以应该在 getter/setter 中创建一个防御性副本。这可以按照您的方式完成,也可以通过使用提供不可变对象的新 Java Time API 来完成。
Assigning an Object to null is a code smell. Consider refactoring
将对象分配给 null 是一种代码异味。考虑重构
IMO dubious one. The issue is raised by PMD plugin (which is the tool analyzing the code, SonarQube is displaying the report). Issue is raised by this rule http://pmd.sourceforge.net/pmd-4.3.0/rules/controversial.html#NullAssignment, as you can see it is in controversial category. I don't think there is anything wrong with your code, and proper action might be to ignore this warning and mark the issue as "won't fix". You can also configure your SonarQube to not use this particular rule in your Quality Profile setting.
海事组织可疑的一个。这个问题是由 PMD 插件提出的(这是分析代码的工具,SonarQube 正在显示报告)。此规则引发了问题http://pmd.sourceforge.net/pmd-4.3.0/rules/controversial.html#NullAssignment,正如您所看到的,它属于有争议的类别。我认为您的代码没有任何问题,正确的操作可能是忽略此警告并将问题标记为“无法修复”。您还可以将 SonarQube 配置为不在质量配置文件设置中使用此特定规则。
Return an empty collection instead of null.
返回一个空集合而不是 null。
You did not provide the code which is triggering it, but this seems to be a valid piece of advice. It is generally better to return empty collections rather than nulls.
您没有提供触发它的代码,但这似乎是一条有效的建议。通常最好返回空集合而不是空集合。