使用错误查找器插件,我发现了此错误,但不明白为什么在代码中将其视为错误。有人知道这些并给我适当的解释吗?谢谢。
源代码-https://drive.google.com/open?id=1gAyHFcdHBShV-9oC5G7GeOtCGf7bXoso;
Patient.java:17 Patient.generatePriority()使用Random的nextDouble方法生成随机整数;使用nextInt效率更高[关注度(18),正常置信度]
public int generatePriority(){
Random random = new Random();
int n = 5;
return (int)(random.nextDouble()*n);
}
[ExaminationRoom.java:25 ExaminationRoom定义了等于并使用Object.hashCode()[Of Concern(16),正常置信度]
public boolean equals(ExaminationRoom room){
if (this.getWaitingPatients().size() == room.getWaitingPatients().size()){
return true;
}
else {
return false;
}
}
[ExaminationRoom.java:15 ExaminationRoom定义compareTo(ExaminationRoom)并使用Object.equals()[Of Concern(16),正常可信度]
// Compares sizes of waiting lists
@Override
public int compareTo(ExaminationRoom o) {
if (this.getWaitingPatients().size() > o.getWaitingPatients().size()){
return 1;
}
else if (this.getWaitingPatients().size() < o.getWaitingPatients().size()){
return -1;
}
return 0;
}
Hospital.java:41不好的月份值12传递给Hospital.initializeHospital()中的新java.util.GregorianCalendar(int,int,int)[Scary(7),正常可信度]
doctors.add(new Doctor("Hermione", "Granger", new GregorianCalendar(1988, 12, 10), Specialty.PSY, room102));
Person.java:29 Person.getFullName()中忽略的String.toLowerCase()返回值[Scariest(3),高置信度]
public String getFullName(){
firstName.toLowerCase();
Character.toUpperCase(firstName.charAt(0));
lastName.toLowerCase();
Character.toUpperCase(lastName.charAt(0));
return firstName + " " + lastName;
}
关于“错误查找器”工具的第一件事要记住,它们通常只是指导原则。这样说:
GregorianCalendar
类从0开始数月,表示0是一月,11是十二月。 12表示不存在的第13个月。由于该函数期望一个int
,并且您给了它一个int
,因此即使肯定是一个错误,也不会生成编译器错误。本文很好地解释了升级原因,并提供了有关如何使用新API的示例:https://www.baeldung.com/java-8-date-time-intro
如果有疑问,您可以随时检查文档。在这种情况下,类Calendar
(GregorianCalendar
进行了扩展)将保留一个静态常量public static final int JANUARY = 0;
。这确认一月的确是0
,但也表明我们可以在代码中使用此常量。您可能会发现new GregorianCalendar(1988, Calendar.JANUARY, 10)
更具可读性。
您可能还想考虑切换到用于处理时间的更现代,更标准的系统。 Java 8 Time库是“新标准”,绝对值得研究。
第二,String
在Java中是不可变的。这意味着一旦创建了String
,就永远无法更改其值。这可能与您的直觉背道而驰,因为您可能已经看到诸如以下的代码:
String s = "hello";
s = s + " world";
但是,这不是modify字符串s
。相反,s + " world"
创建一个新的String
,并将其分配给变量s
。
类似地,s.toLowerCase()
不会更改s
,它只会生成一个新的String
,您必须将其分配。
您可能想要firstName = firstName.toLowerCase();
[对于您的第一个示例,没有什么立即让我感到“不好”,但是如果您查看工具生成的消息,它们会将第一个示例标记为“关注”,但将其他示例标记为(例如[C0 ]示例)为“可怕” /“可怕”。尽管我对这个工具不是特别熟悉,但我认为这表明它更多的是“代码气味”,而不是实际的错误。
如果您想确保自己的代码可以工作,请考虑使用单元测试。
string.toLowerCase()
对象。Random
。random.nextInt(n)
中定义hashCode
方法。ExaminationRoom
方法为与compareTo
不一致可能或可能不正确。equals()
代替LocalDate
。GregorianCalendar
和String.toLowerCase()
中的返回值。Character.toUpperCase()
每次需要时创建一个新的Random
对象都会给较差的伪随机数带来重复出现数字的高风险。在方法外声明一个持有Random
对象的静态变量,并在声明中对其进行初始化(Random
是线程安全的,因此可以放心地执行此操作)。要绘制从0到4的伪随机数,请使用
Random
不仅效率更高(如FindBugs所说,我首先发现它更具可读性。
int n = 5;
return random.nextInt(n);
hashCode()
@Override
public int hashCode() {
return Objects.hash(getWaitingPatients());
}
您向我们展示的compareTo()
方法似乎与这里的FindBugs相矛盾。但是,它看起来确实有点可笑。如果两个候诊室的候诊人数相同,是否将它们视为相同?请再想一想。如果最终决定它们不相等,但应毫无区别地分类到同一位置,则您的equals
方法与compareTo
不一致。如果是这样,请插入评论说明这一事实。如果不希望FindBugs在以后的分析中将其报告为错误,则有两种选择:
很抱歉,我不记得每个细节,但是您的搜索引擎应该会有所帮助。
请勿使用equals()
GregorianCalendar
类的设计很差,而且已经过时了。我建议您从代码中逐出它,而改用java.time(现代Java日期和时间API)中的GregorianCalendar
。
LocalDate
doctors.add(new Doctor("Hermione", "Granger", LocalDate.of(1988, Month.DECEMBER, 10), Specialty.PSY, room102));
在其他答案中已经对此进行了处理。更改名称以使首字母大写,其余字母小写并不像听起来那么简单。
String.toLowerCase()
这两行的第一行不会修改字符串firstName.toLowerCase();
Character.toUpperCase(firstName.charAt(0));
,因为字符串被设计为不可变的,并且firstName
返回的new字符串全部为小写字母(根据的规则) JVM的默认语言环境,令人困惑)。第二行也不会修改任何字符,因为Java是按值调用(查找它),因此没有方法可以修改作为参数传递的变量。您甚至没有传递变量,而是传递不同方法的返回值。同样,toLowerCase()
返回小写的new字符。
[您需要做的是拾取从这两个方法调用返回的值,使用子字符串操作从名称的小写字母中删除第一个字母,并将该字母的大写字母与其余字母连接起来小写字符串。如果很复杂,我相信您的搜索引擎可以找到在何处以及如何完成的示例。
SpotBugs
这只是我所听到的,我还没有检查自己。 FindBugs的源代码已由一个名为SpotBugs的项目接管。他们说SpotBugs的开发比FindBugs更加积极。因此,您可以考虑进行切换。我本人是日常工作中快乐的SpotBugs用户。
Character.toUpperCase()
Comparable
与Comparable
不一致的含义以及处理方法。compareTo()
解释如何使用java.time。equals(