FindBugs插件Eclipse发现的错误

问题描述 投票:0回答:2

使用错误查找器插件,我发现了此错误,但不明白为什么在代码中将其视为错误。有人知道这些并给我适当的解释吗?谢谢。

源代码-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;

}
java eclipse findbugs spotbugs
2个回答
0
投票

关于“错误查找器”工具的第一件事要记住,它们通常只是指导原则。这样说:

GregorianCalendar类从0开始数月,表示0是一月,11是十二月。 12表示不存在的第13个月。由于该函数期望一个int,并且您给了它一个int,因此即使肯定是一个错误,也不会生成编译器错误。本文很好地解释了升级原因,并提供了有关如何使用新API的示例:https://www.baeldung.com/java-8-date-time-intro

如果有疑问,您可以随时检查文档。在这种情况下,类CalendarGregorianCalendar进行了扩展)将保留一个静态常量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 ]示例)为“可怕” /“可怕”。尽管我对这个工具不是特别熟悉,但我认为这表明它更多的是“代码气味”,而不是实际的错误。

如果您想确保自己的代码可以工作,请考虑使用单元测试。


0
投票
  1. 不要每次都创建一个新的string.toLowerCase()对象。
  2. 使用Random
  3. random.nextInt(n)中定义hashCode方法。
  4. 使ExaminationRoom方法为compareTo不一致可能或可能不正确。
  5. 使用equals()代替LocalDate
  6. 拾取并使用GregorianCalendarString.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在以后的分析中将其报告为错误,则有两种选择:

  1. 插入一个注释,告诉FindBugs忽略“错误”。
  2. 创建包含此点的FindBugs忽略XML文件。

很抱歉,我不记得每个细节,但是您的搜索引擎应该会有所帮助。

请勿使用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用户。

链接

© www.soinside.com 2019 - 2024. All rights reserved.