FindBugs质量管理

1. Find B ugs是什么

FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。有了静态分析工具,就可以在不实际运行程序的情况对软件进行分析。

FindBugs就是对编译后的class进行扫描,以发现一些隐藏的bug。如果你拥有这些.class档对应的代码文件,可把这些源代码文件再选上,这样便可以从稍后得出的报告中快捷的定位到出问题的代码上面。此外,还可以选上工程所使用的library,这样似乎可以帮助FindBugs做一些高阶的检查,以发现一些更深层的bug。

2. Find B ugs 的作用

使用FindBugs一般建议是在开发阶段,在这个阶段将 FindBugs 加入到编译过程中,可以尽可能早地在进行编译时发现问题,从而保证保证项目研发质量。尤其当团队扩大,并且不可避免地在项目中加入更多新开发人员时,FindBugs 可以作为一个安全网,检测出已经识别的缺陷模式。如果让一定数量的开发人员共同工作,那么在代码中就会出现缺陷。像 FindBugs 这样的工具当然不会找出所有的缺陷,但是它们会帮助找出其中的部分。

一旦确定了加入哪些过滤器和类,运行 FindBugs 就没什么成本了,而带来的好处就是它会检测出新缺陷。如果编写特定于应用程序的检测器,则这个好处可能更大。

3. Find B ugs 的使用

FindBugs的使用一般分为独立使用和集成使用,独立使用是指单独安装FindBugs程序,然后在命令行或其他流程中全套使用,如DevOps平台。嵌入使用一般是与开发工具或集成工具使用,如eclipse、idea、Jenkins等。

4. Find B ugs 规则分类

FindBugs的规则在3.0.1版本中一共有453个,规则分为八类,分别为:

l Bad practice:不好的实践方面的

l Correctness:正确性方面的

l Internationalization:国际化的方面的

l Malicious code vulnerability:存在漏洞的有害代码方面的

l Multithreaded correctness:多线程正确性方面的

l Performance:性能 方面的

l Security:安全方面的

l Dodgy code:不可靠代码方面的

5. FindBugs规则详情

|------------------------------|---------------------------------------------------------|--------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 规格分类英文 | 错误码 | 错误规则 | 中文翻译 |
| Bad practice | AM_CREATES_EMPTY_JAR_FILE_ENTRY | AM: Creates an empty jar file entry | 调用putNextEntry()方法写入新的 jar 文件条目时立即调用closeEntry()方法。这样会造成JarFile条目为空。 |
| Bad practice | AM_CREATES_EMPTY_ZIP_FILE_ENTRY | AM: Creates an empty zip file entry | 调用putNextEntry()方法写入新的 zip 文件条目时立即调用closeEntry()方法。这样会造成ZipFile条目为空。 |
| Bad practice | BC_EQUALS_METHOD_SHOULD_WORK_FOR_ALL_OBJECTS | BC: Equals method should not assume anything about the type of its argument | equals(Object o)方法不能对参数o的类型做任何的假设。比较此对象与指定的对象。当且仅当该参数不为 null,并且是表示与此对象相同的类型的对象时,结果才为 true。 |
| Bad practice | BIT_SIGNED_CHECK | BIT: Check for sign of bitwise operation | 检查位操作符运行是否合理 ((event.detail & SWT.SELECTED) > 0) If SWT.SELECTED is a negative number, this is a candidate for a bug. Even when SWT.SELECTED is not negative, it seems good practice to use '!= 0' instead of '> 0'. |
| Bad practice | CN_IDIOM | CN: Class implements Cloneable but does not define or use clone method | 按照惯例,实现此接口的类应该使用公共方法重写 Object.clone(它是受保护的),以获得有关重写此方法的详细信息。此接口不 包含 clone 方法。因此,因为某个对象实现了此接口就克隆它是不可能的,应该实现此接口的类应该使用公共方法重写 Object.clone |
| Bad practice | CN_IDIOM_NO_SUPER_CALL | CN: clone method does not call super.clone() | 一个非final类型的类定义了clone()方法而没有调用super.clone()方法。例如:B扩展自A,如果B中clone方法调用了spuer.clone(),而A中的clone没有调用spuer.clone(),就会造成结果类型不准确。要求A的clone方法中调用spuer.clone()方法。 |
| Bad practice | CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE | CN: Class defines clone() but doesn't implement Cloneable | 类中定义了clone方法但是它没有实现Cloneable接口 |
| Bad practice | CNT_ROUGH_CONSTANT_VALUE | CNT: Rough value of known constant found | 建议使用预定义的库常量以提高代码的清晰度和精度。 |
| Bad practice | CO_ABSTRACT_SELF | Co: Abstract class defines covariant compareTo() method | 抽象类中定义了多个compareTo()方法,正确的是覆写Comparable中的compareTo方法,方法的参数为Object类型,如下例: int compareTo(T o) 比较此对象与指定对象的顺序。 |
| Bad practice | CO_COMPARETO_INCORRECT_FLOATING | Co: compareTo()/compare() incorrectly handles float or double value | 此方法使用如下模式比较双值或浮点值:val1>val2?1:val1<val2-1 : 0. 此模式不适用于-0.0和NaN值,这可能会导致不正确的排序结果或集合损坏(如果将比较值用作键)。考虑使用Double.compare或Float.com.pare静态方法,这些方法可以正确处理所有特殊情况。 |
| Bad practice | CO_COMPARETO_RESULTS_MIN_VALUE | Co: compareTo()/compare() returns Integer.MIN_VALUE | 在某些情况下,此compareTo或compare方法返回常量Integer。MIN_VALUE,这是一种异常糟糕的做法。compareTo的返回值唯一重要的是结果的符号。但人们有时会否定compareTo的返回值,以为这会否定结果的符号。它会的,除非返回的值是Integer。最小值。所以只需返回-1而不是Integer。最小值。 |
| Bad practice | CO_SELF_NO_OBJECT | Co: Covariant compareTo() method defined | 类中定义了多个compareTo()方法,正确的是覆写Comparable中的compareTo方法,方法的参数为Object类型 |
| Bad practice | DE_MIGHT_DROP | DE: Method might drop exception | 方法可能抛出异常 |
| Bad practice | DE_MIGHT_IGNORE | DE: Method might ignore exception | 方法可能忽略异常 |
| Bad practice | DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS | DMI: Adding elements of an entry set may fail due to reuse of Entry objects | entrySet()方法被允许返回底层Map的视图,在该视图中,单个Entry对象在迭代过程中被重用并返回。从Java 1.6开始,IdentityHashMap和EnumMap都是这样做的。当迭代这样的Map时,Entry值只有在进入下一次迭代之前才有效。例如,如果您试图将这样一个entrySet传递给addAll方法,那么事情就会严重出错。 |
| Bad practice | DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION | DMI: Don't use removeAll to clear a collection | 不要用removeAll方法去clear一个集合 |
| Bad practice | DM_EXIT | Dm: Method invokes System.exit(...) | 在方法中调用System.exit(...)语句,考虑用RuntimeException来代替 |
| Bad practice | DM_RUN_FINALIZERS_ON_EXIT | Dm: Method invokes dangerous method runFinalizersOnExit | 在方法中调用了System.runFinalizersOnExit 或者Runtime.runFinalizersOnExit方法,因为这样做是很危险的。 |
| Bad practice | ES_COMPARING_PARAMETER_STRING_WITH_EQ | ES: Comparison of String parameter using == or != | 用==或者!=方法去比较String类型的参数 |
| Bad practice | ES_COMPARING_STRINGS_WITH_EQ | ES: Comparison of String objects using == or != | 用==或者!=去比较String类型的对象 |
| Bad practice | EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS | Eq: Equals checks for incompatible operand | equals方法检查不一致的操作。两个类根本就是父子关系而去调用equals方法去判读对象是否相等。 public boolean equals(Object o) { if (o instanceof Foo) return name.equals(((Foo)o).name); else if (o instanceof String) return name.equals(o); else return false; |
| Bad practice | EQ_COMPARETO_USE_OBJECT_EQUALS | Eq: Class defines compareTo(...) and uses Object.equals() | 类中定义了compareTo方法但是继承了Object中的compareTo方法 |
| Bad practice | EQ_GETCLASS_AND_CLASS_CONSTANT | Eq: equals method fails for subtypes | 类中的equals方法可能被子类中的方法所破坏,当使用类似于Foo.class == o.getClass()的判断时考虑用this.getClass() == o.getClass()来替换 |
| Bad practice | EQ_SELF_NO_OBJECT | Eq: Covariant equals() method defined | 类中定义了多个equals方法。正确的做法是覆写Object中的equals方法,它的参数为Object类型的对象。 |
| Bad practice | FI_EMPTY | FI: Empty finalizer should be deleted | 为空的finalizer方法应该删除。一下关于finalizer的内容省略 |
| Bad practice | HE_EQUALS_NO_HASHCODE | HE: Class defines equals() but not hashCode() | 方法定义了equals方法却没有定义hashCode方法 |
| Bad practice | HE_HASHCODE_NO_EQUALS | HE: Class defines hashCode() but not equals() | 类定义了hashCode方法去没有定义equal方法 |
| Bad practice | HE_EQUALS_USE_HASHCODE | HE: Class defines hashCode() and uses Object.equals() | 一个类覆写了equals方法,没有覆写hashCode方法,使用了Object对象的hashCode方法 |
| Bad practice | HE_INHERITS_EQUALS_USE_HASHCODE | HE: Class inherits equals() and uses Object.hashCode() | 子类继承了父类的equals方法却使用了Object的hashCode方法 |
| Bad practice | IMSE_DONT_CATCH_IMSE | IMSE: Dubious catching of IllegalMonitorStateException | 捕捉违法的监控状态异常,例如当没有获取到对象锁时使用其wait和notify方法 |
| Bad practice | ISC_INSTANTIATE_STATIC_CLASS | ISC: Needless instantiation of class that only supplies static methods | 为使用静态方法而创建一个实例对象。调用静态方法时只需要使用类名+静态方法名就可以了。 |
| Bad practice | IT_NO_SUCH_ELEMENT | It: Iterator next() method can't throw NoSuchElementException | 迭代器的next方法不能够抛出NoSuchElementException |
| Bad practice | J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION | J2EE: Store of non serializable object into HttpSession | 在HttpSession对象中保存非连续的对象 |
| Bad practice | JCIP_FIELD_ISNT_FINAL_IN_IMMUTABLE_CLASS | JCIP: Fields of immutable classes should be final | The class is annotated with net.jcip.annotations.Immutable, and the rules for that annotation require that all fields are final. . |
| Bad practice | NP_BOOLEAN_RETURN_NULL | NP: Method with Boolean return type returns explicit null | 返回值为boolean类型的方法直接返回null,这样会导致空指针异常 |
| Bad practice | NP_EQUALS_SHOULD_HANDLE_NULL_ARGUMENT | NP: equals() method does not check for null argument | 变量调用equals方法时没有进行是否为null的判断 |
| Bad practice | NP_TOSTRING_COULD_RETURN_NULL | NP: toString method may return null | toString方法可能返回null |
| Bad practice | NM_CLASS_NAMING_CONVENTION | Nm: Class names should start with an upper case letter | 类的名称以大写字母名称开头 |
| Bad practice | NM_CLASS_NOT_EXCEPTION | Nm: Class is not derived from an Exception, even though it is named as such | 类的名称中含有Exception但是却不是一个异常类的子类,这种名称会造成混淆 |
| Bad practice | NM_CONFUSING | Nm: Confusing method names | 令人迷惑的方面命名 |
| Bad practice | NM_FIELD_NAMING_CONVENTION | Nm: Field names should start with a lower case letter | 非final类型的字段需要遵循驼峰命名原则 |
| Bad practice | NM_FUTURE_KEYWORD_USED_AS_IDENTIFIER | Nm: Use of identifier that is a keyword in later versions of Java | 验证是否是java预留关键字 |
| Bad practice | NM_FUTURE_KEYWORD_USED_AS_MEMBER_IDENTIFIER | Nm: Use of identifier that is a keyword in later versions of Java | 验证是否是java预留关键字 |
| Bad practice | NM_METHOD_NAMING_CONVENTION | Nm: Method names should start with a lower case letter | 方法名称以小写字母开头 |
| Bad practice | NM_SAME_SIMPLE_NAME_AS_INTERFACE | Nm: Class names shouldn't shadow simple name of implemented interface | 实现同一接口实现类不能使用相同的名称,即使它们位于不同的包中 |
| Bad practice | NM_SAME_SIMPLE_NAME_AS_SUPERCLASS | Nm: Class names shouldn't shadow simple name of superclass | 继承同一父类的子类不能使用相同的名称,即使它们位于不同的包中 |
| Bad practice | NM_VERY_CONFUSING_INTENTIONAL | Nm: Very confusing method names (but perhaps intentional) | 很容易混淆的方法命名,例如方法的名称名称使用使用大小写来区别两个不同的方法。 |
| Bad practice | NM_WRONG_PACKAGE_INTENTIONAL | Nm: Method doesn't override method in superclass due to wrong package for parameter | 由于错误引用了不同包中相同类名的对象而不能够正确的覆写父类中的方法 import alpha.Foo; public class A { public int f(Foo x) { return 17; } } import beta.Foo; public class B extends A { public int f(Foo x) { return 42; } public int f(alpha.Foo x) { return 27; } } |
| Bad practice | OBL_UNSATISFIED_OBLIGATION | ODR: Method may fail to close database resource | 这种方法可能无法清除(关闭,处置)一个流,数据库对象,或其他资源需要一个明确的清理行动。 一般来说,如果一个方法打开一个流或其他资源,该方法应该使用try / finally块来确保在方法返回之前流或资源已经被清除了。这种错误模式基本上和OS_OPEN_STREAM和ODR_OPEN_DATABASE_RESOURCE错误模式相同,但是是在不同在静态分析技术。我们正为这个错误模式的效用收集反馈意见。 |
| Bad practice | ODR_OPEN_DATABASE_RESOURCE | ODR: Method may fail to close database resource on exception | 方法中可能存在关闭数据连接失败的情况 |
| Bad practice | OS_OPEN_STREAM | OS: Method may fail to close stream | 方法中可能存在关闭流失败的情况 |
| Bad practice | OS_OPEN_STREAM_EXCEPTION_PATH | OS: Method may fail to close stream on exception | 方法中可能存在关闭流时出现异常情况 |
| Bad practice | RC_REF_COMPARISON_BAD_PRACTICE | RC: Suspicious reference comparison to constant | 当两者为不同类型的对象时使用equals方法来比较它们的值是否相等,而不是使用==方法。例如比较的两者为java.lang.Integer, java.lang.Float |
| Bad practice | RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN | RC: Suspicious reference comparison of Boolean values | 使用== 或者 !=操作符来比较两个 Boolean类型的对象,建议使用equals方法。 |
| Bad practice | RR_NOT_CHECKED | RR: Method ignores results of InputStream.read() | InputStream.read方法忽略返回的多个字符,如果对结果没有检查就没法正确处理用户读取少量字符请求的情况。 |
| Bad practice | SR_NOT_CHECKED | RR: Method ignores results of InputStream.skip() | InputStream.skip()方法忽略返回的多个字符,如果对结果没有检查就没法正确处理用户跳过少量字符请求的情况 |
| Bad practice | RV_RETURN_VALUE_IGNORED_BAD_PRACTICE | RV: Method ignores exceptional return value | 方法忽略返回值的异常信息 |
| Bad practice | SI_INSTANCE_BEFORE_FINALS_ASSIGNED | SI: Static initializer creates instance before all static final fields assigned | 在所有的static final字段赋值之前去使用静态初始化的方法创建一个类的实例。 |
| Bad practice | SE_BAD_FIELD_STORE | Se: Non-serializable value stored into instance field of a serializable class | 非序列化的值保存在声明为序列化的的非序列化字段中 |
| Bad practice | SE_COMPARATOR_SHOULD_BE_SERIALIZABLE | Se: Comparator doesn't implement Serializable | Comparator接口没有实现Serializable接口 |
| Bad practice | SE_INNER_CLASS | Se: Serializable inner class | 序列化内部类 |
| Bad practice | SE_NONFINAL_SERIALVERSIONID | Se: serialVersionUID isn't final | 关于UID类的检查内容省略 |
| Bad practice | SE_NO_SUITABLE_CONSTRUCTOR | Se: Class is Serializable but its superclass doesn't define a void constructor | 子类序列化时父类没有提供一个void的构造函数 |
| Bad practice | SE_NO_SUITABLE_CONSTRUCTOR_FOR_EXTERNALIZATION | Se: Class is Externalizable but doesn't define a void constructor | Externalizable 实例类没有定义一个void类型的构造函数 |
| Bad practice | SE_READ_RESOLVE_MUST_RETURN_OBJECT | Se: The readResolve method must be declared with a return type of Object. | readResolve从流中读取类的一个实例,此方法必须声明返回一个Object类型的对象 |
| Bad practice | UI_INHERITANCE_UNSAFE_GETRESOURCE | UI: Usage of GetResource may be unsafe if class is extended | 当一个类被子类继承后不要使用this.getClass().getResource(...)来获取资源 |
| Correctness | BC_IMPOSSIBLE_CAST | BC: Impossible cast | 不可能的类转换,执行时会抛出ClassCastException |
| Correctness | BC_IMPOSSIBLE_DOWNCAST | BC: Impossible downcast | 父类在向下进行类型转换时抛出ClassCastException |
| Correctness | BC_IMPOSSIBLE_INSTANCEOF | BC: instanceof will always return false | 采用instaneof方法进行比较时总是返回false。前提是保证它不是由于某些逻辑错误造成的。 |
| Correctness | BIT_AND | BIT: Incompatible bit masks | 错误的使用&位操作符,例如(e & C) |
| Correctness | BIT_AND_ZZ | BIT: Check to see if ((...) & 0) == 0 | 检查恒等的逻辑错误 |
| Correctness | BIT_IOR | BIT: Incompatible bit masks | 错误的使用|位操作符,例如(e | C) |
| Correctness | BIT_SIGNED_CHECK_HIGH_BIT | BIT: Check for sign of bitwise operation | 检查逻辑运算符操作返回的标识。例如((event.detail & SWT.SELECTED) > 0),建议采用!=0代替>0 |
| Correctness | BOA_BADLY_OVERRIDDEN_ADAPTER | BOA: Class overrides a method implemented in super class Adapter wrongly | 子类错误的覆写父类中用于适配监听其他事件的方法,从而导致当触发条件发生时不能被监听者调用 |
| Correctness | DLS_DEAD_STORE_OF_CLASS_LITERAL | DLS: Dead store of class literal | 以类的字面名称方式为一个字段赋值后再也没有去使用它,在1.4jdk中它会自动调用静态的初始化方法,而在jdk1.5中却不会去执行。 |
| Correctness | DLS_OVERWRITTEN_INCREMENT | DLS: Overwritten increment | 覆写增量增加错误i = i++ |
| Correctness | DMI_BAD_MONTH | DMI: Bad constant value for month | 月份的错误常量值 |
| Correctness | DMI_COLLECTIONS_SHOULD_NOT_CONTAIN_THEMSELVES | DMI: Collections should not contain themselves | 集合没有包含他们自己本身。 |
| Correctness | DMI_INVOKING_HASHCODE_ON_ARRAY | DMI: Invocation of hashCode on an array | 数组直接使用hashCode方法来返回哈希码。 int [] a1 = new int[]{1,2,3,4}; System.out.println(a1.hashCode()); System.out.println(java.util.Arrays.hashCode(a1)); |
| Correctness | DMI_VACUOUS_SELF_COLLECTION_CALL | DMI: Vacuous call to collections | 集合的调用不能被感知。例如c.containsAll(c)总是返回true,而c.retainAll(c)的返回值不能被感知。 |
| Correctness | DMI_ANNOTATION_IS_NOT_VISIBLE_TO_REFLECTION | Dm: Can't use reflection to check for presence of annotation without runtime retention | Unless an annotation has itself been annotated with @Retention(RetentionPolicy.RUNTIME), the annotation can't be observed using reflection (e.g., by using the isAnnotationPresent method). . |
| Correctness | EC_ARRAY_AND_NONARRAY | EC: equals() used to compare array and nonarray | 数组对象使用equals方法和非数组对象进行比较。即使比较的双方都是数组对象也不应该使用equals方法,而应该比较它们的内容是否相等使用java.util.Arrays.equals(Object[], Object[]); |
| Correctness | EC_INCOMPATIBLE_ARRAY_COMPARE | EC: equals(...) used to compare incompatible arrays | 使用equls方法去比较类型不相同的数组。例如:String[] and StringBuffer[], or String[] and int[] |
| Correctness | EC_UNRELATED_CLASS_AND_INTERFACE | EC: Call to equals() comparing unrelated class and interface | 使用equals方法比较不相关的类和接口 |
| Correctness | EC_UNRELATED_INTERFACES | EC: Call to equals() comparing different interface types | 调用equals方法比较不同类型的接口 |
| Correctness | EC_UNRELATED_TYPES | EC: Call to equals() comparing different types | 调用equals方法比较不同类型的类 |
| Correctness | EC_UNRELATED_TYPES_USING_POINTER_EQUALITY | EC: Using pointer equality to compare different types | This method uses using pointer equality to compare two references that seem to be of different types. The result of this comparison will always be false at runtime. |
| Correctness | EQ_ALWAYS_FALSE | Eq: equals method always returns false | 使用equals方法返回值总是false |
| Correctness | EQ_ALWAYS_TRUE | Eq: equals method always returns true | equals方法返回值总是true |
| Correctness | EQ_COMPARING_CLASS_NAMES | Eq: equals method compares class names rather than class objects | 使用equals方法去比较一个类的实例和类的类型 |
| Correctness | EQ_OTHER_NO_OBJECT | Eq: equals() method defined that doesn't override equals(Object) | 类中定义的equals方法时不要覆写equals(Object)方法 |
| Correctness | EQ_OTHER_USE_OBJECT | Eq: equals() method defined that doesn't override Object.equals(Object) | 类中定义的equals方法时不要覆写Object中的equals(Object)方法 |
| Correctness | EQ_SELF_USE_OBJECT | Eq: Covariant equals() method defined, Object.equals(Object) inherited | 类中定义了一组equals方法,但是都是继承的java.lang.Object class中的equals(Object)方法 |
| Correctness | VA_FORMAT_STRING_BAD_ARGUMENT | FS: Format string placeholder incompatible with passed argument | 错误使用参数类型来格式化字符串 |
| Correctness | VA_FORMAT_STRING_BAD_CONVERSION | FS: The type of a supplied argument doesn't match format specifier | 指定的格式字符串和参数类型不匹配,例如:String.format("%d", "1") |
| Correctness | VA_FORMAT_STRING_EXPECTED_MESSAGE_FORMAT_SUPPLIED | FS: MessageFormat supplied where printf style format expected | 但用String的format方法时实际调用了MessageFormat中干的格式化方法而引起格式化结果出错。 |
| Correctness | VA_FORMAT_STRING_EXTRA_ARGUMENTS_PASSED | FS: More arguments are passed than are actually used in the format string | 使用String的format方法时有非法的参数也经过了格式化操作。 |
| Correctness | VA_FORMAT_STRING_ILLEGAL | FS: Illegal format string | 格式化String对象语句错误 |
| Correctness | VA_FORMAT_STRING_MISSING_ARGUMENT | FS: Format string references missing argument | String的format操作缺少必要的参数。 |
| Correctness | VA_FORMAT_STRING_NO_PREVIOUS_ARGUMENT | FS: No previous argument for format string | 格式字符串定义错误,例如:formatter.format("%<s %s", "a", "b"); 抛出MissingFormatArgumentException异常 |
| Correctness | ICAST_INT_CAST_TO_DOUBLE_PASSED_TO_CEIL | ICAST: Integral value cast to double and then passed to Math.ceil | integral的值转换为double后使用了Math.ceil方法 |
| Correctness | ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND | ICAST: int value cast to float and then passed to Math.round | int 类型的值转换为float类型之后调用了Math.round方法 |
| Correctness | IJU_ASSERT_METHOD_INVOKED_FROM_RUN_METHOD | IJU: JUnit assertion in run method will not be noticed by JUnit | 在JUnit中的断言在run方法中不会被告知 |
| Correctness | IJU_BAD_SUITE_METHOD | IJU: TestCase declares a bad suite method | 在一个JUnit类中声明的一个suite()方法必须声明为 public static junit.framework.Test suite() 或者 public static junit.framework.TestSuite suite()的形式。 |
| Correctness | IL_CONTAINER_ADDED_TO_ITSELF | IL: A collection is added to itself | 集合本身作为add方法的参数,这样会引起内容溢出。 |
| Correctness | IL_INFINITE_LOOP | IL: An apparent infinite loop | 方法的自调用引起的死循环 |
| Correctness | IM_MULTIPLYING_RESULT_OF_IREM | IM: Integer multiply of result of integer remainder | 和整数余数进行乘法运算。例如:i % 60 * 1000 是进行(i % 60) * 1000运算而不是 i % (60 * 1000) |
| Correctness | INT_BAD_COMPARISON_WITH_NONNEGATIVE_VALUE | INT: Bad comparison of nonnegative value with negative constant or zero | 保证非负数和负数进行比较 |
| Correctness | INT_BAD_COMPARISON_WITH_SIGNED_BYTE | INT: Bad comparison of signed byte | 比较有符合数,要先把有符号数转换为无符合数再进行比较 |
| Correctness | IO_APPENDING_TO_OBJECT_OUTPUT_STREAM | IO: Doomed attempt to append to an object output stream | 宣布试图在对象的输出流处添加元素,如果你希望能够添加进一个对象的输出流中必须保证对象的输出流处于打开状态。 |
| Correctness | IP_PARAMETER_IS_DEAD_BUT_OVERWRITTEN | IP: A parameter is dead upon entry to a method but overwritten | 传入参数的值被忽略,但是对传入值进行了修改,并返回给了调用者 |
| Correctness | MF_CLASS_MASKS_FIELD | MF: Class defines field that masks a superclass field | 子类中定义了和父类中同名的字段。在调用时会出错 |
| Correctness | MF_METHOD_MASKS_FIELD | MF: Method defines a variable that obscures a field | 在方法中定义的局部变量和类变量或者父类变量同名,从而引起字段混淆。 |
| Correctness | NP_ALWAYS_NULL | NP: Null pointer dereference | 对象赋为null值后 没有被重新赋值 |
| Correctness | NP_ALWAYS_NULL_EXCEPTION | NP: Null pointer dereference in method on exception path | 空指针引用上调用去除引用方法,将发生空指针异常 |
| Correctness | NP_ARGUMENT_MIGHT_BE_NULL | NP: Method does not check for null argument | 方法没有判断参数是否为空 |
| Correctness | NP_CLOSING_NULL | NP: close() invoked on a value that is always null | 一个为空的对象调用close方法 |
| Correctness | NP_GUARANTEED_DEREF | NP: Null value is guaranteed to be dereferenced | 在正常的null判断分支上,对象去除引用操作是受保护的不允许的 |
| Correctness | NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH | NP: Value is null and guaranteed to be dereferenced on exception path | There is a statement or branch on an exception path that if executed guarantees that a value is null at this point, and that value that is guaranteed to be dereferenced (except on forward paths involving runtime exceptions). |
| Correctness | NP_NONNULL_PARAM_VIOLATION | NP: Method call passes null to a non-null parameter | 方法中为null的参数没有被重新赋值 void test(){ String ss = null; sya(ss); } public void sya(String ad){ ad.getBytes(); } |
| Correctness | NP_NONNULL_RETURN_VIOLATION | NP: Method may return null, but is declared @Nonnull | 方法声明了返回值不能为空,但是方法中有可能返回null |
| Correctness | NP_NULL_INSTANCEOF | NP: A known null value is checked to see if it is an instance of a type | 检查一个为null的值是否是想要的类型对象,而不是由于粗心或者逻辑错误引起的 |
| Correctness | NP_NULL_ON_SOME_PATH | NP: Possible null pointer dereference | 对象可能没有重新赋值 |
| Correctness | NP_NULL_ON_SOME_PATH_EXCEPTION | NP: Possible null pointer dereference in method on exception path | 在异常null值处理分支调用的方法上,可能存在对象去除引用操作 |
| Correctness | NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS | NP: Method call passes null for non-null parameter | 方法参数中声明为nonnull类型的参数为null void test(){ String ss = null; sya(ss); } public void sya(@nonnull String ad){ ad.getBytes(); } |
| Correctness | NP_STORE_INTO_NONNULL_FIELD | NP: Store of null value into field annotated @Nonnull | 为一个已经声明为不能为null值的属性赋值为null。 |
| Correctness | NM_BAD_EQUAL | Nm: Class defines equal(Object); should it be equals(Object)? | 类中定义了一个equal方法但是却不是覆写的Object对象的equals方法 |
| Correctness | NM_LCASE_HASHCODE | Nm: Class defines hashcode(); should it be hashCode()? | 类中定义了一个hashCode方法但是却不是覆写的Object中的hashCode方法 |
| Correctness | NM_LCASE_TOSTRING | Nm: Class defines tostring(); should it be toString()? | 类中定义了一个toString方法但是却不是覆写的Object中的toString方法 |
| Correctness | NM_METHOD_CONSTRUCTOR_CONFUSION | Nm: Apparent method/constructor confusion | 构造方法定义混乱,保证一个标准的构造函数。 例如: SA(){ } void SA(){ } |
| Correctness | NM_VERY_CONFUSING | Nm: Very confusing method names | 混乱的方法命名,如getName和getname方法同时出现的时候 |
| Correctness | NM_WRONG_PACKAGE | Nm: Method doesn't override method in superclass due to wrong package for parameter | 方法因为取了不同包中的同名的对象而没有正确覆写父类中的同名方法 import alpha.Foo; public class A { public int f(Foo x) { return 17; } } ---- import beta.Foo; public class B extends A { public int f(Foo x) { return 42; } } |
| Correctness | QBA_QUESTIONABLE_BOOLEAN_ASSIGNMENT | QBA: Method assigns boolean literal in boolean expression | 再if或者while表达式中使用boolean类型的值时应该使用==去判断,而不是采用=操作 |
| Correctness | RC_REF_COMPARISON | RC: Suspicious reference comparison | 比较两个对象值是否相等时应该采用equals方法,而不是==方法 |
| Correctness | RE_BAD_SYNTAX_FOR_REGULAR_EXPRESSION | RE: Invalid syntax for regular expression | 对正则表达式使用了错误的语法,会抛出未经检查的异常,表明正则表达式模式中的语法错误。 |
| Correctness | RE_CANT_USE_FILE_SEPARATOR_AS_REGULAR_EXPRESSION | RE: File.separator used for regular expression | 使用正则表达式使用了错误的文件分隔符,在windows系统中正则表达式不会匹配'\'而应该使用'\\' |
| Correctness | RV_01_TO_INT | RV: Random value from 0 to 1 is coerced to the integer 0 | 从0到1随机值被强制为整数值0。在强制得到一个整数之前,你可能想得到多个随机值。或使用Random.nextInt(n)的方法。 |
| Correctness | RV_ABSOLUTE_VALUE_OF_HASHCODE | RV: Bad attempt to compute absolute value of signed 32-bit hashcode | 此代码生成一个哈希码,然后计算该哈希码的绝对值。如果哈希码是Integer.MIN_VALUE的,那么结果将是负数(因为Math.abs(Integer.MIN_VALUE的)== Integer.MIN_VALUE的)。 在2^ 32值之外字符串有一个Integer.MIN_VALUE的hashCode包括"polygenelubricants","GydZG_"和","DESIGNING WORKHOUSES "。 |
| Correctness | RV_ABSOLUTE_VALUE_OF_RANDOM_INT | RV: Bad attempt to compute absolute value of signed random integer | 此代码生成一个随机的符号整数,然后计算该随机整数的绝对值。如果随机数生成数绝对值为Integer.MIN_VALUE的,那么结果将是负数(因为Math.abs(Integer.MIN_VALUE的)== Integer.MIN_VALUE的)。 |
| Correctness | RV_EXCEPTION_NOT_THROWN | RV: Exception created and dropped rather than thrown | 此代码创建一个异常(或错误)的对象,但不会用它做任何事情。例如:if (x < 0) new IllegalArgumentException("x must be nonnegative"); 这可能是程序员的意图抛出创建的异常: if (x < 0) throw new IllegalArgumentException("x must be nonnegative"); |
| Correctness | RpC_REPEATED_CONDITIONAL_TEST | RpC: Repeated conditional tests | 该代码包含对同一个条件试验了两次,两边完全一样例如:(如X == 0 | | x == 0)。可能第二次出现是打算判断别的不同条件(如X == 0 | | y== 0)。 |
| Correctness | SA_FIELD_SELF_ASSIGNMENT | SA: Self assignment of field | 方法中包含自己对自己赋值的字段。例如: int x; public void foo() { x = x; } |
| Correctness | SA_FIELD_SELF_COMPARISON | SA: Self comparison of field with itself | 字段自己进行自比较可能表明错误或逻辑错误。 |
| Correctness | SA_LOCAL_SELF_COMPUTATION | SA: Nonsensical self computation involving a field (e.g., x & x) | 此方法对同一变量执行了荒谬的计算(如x&x或x-x)操作。由于计算的性质,这一行动似乎没有意义,并可能表明错误或逻辑错误。 |
| Correctness | SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH | SF: Dead store due to switch statement fall through | 在swtich中先前的case值因为swtich执行失败而被覆写,这就像是忘记使用break推出或者没有使用return语句放回先前的值一样。 |
| Correctness | SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH_TO_THROW | SF: Dead store due to switch statement fall through to throw | 在swtich中因为出现异常而忽略了对case值的保存。 |
| Correctness | SIC_THREADLOCAL_DEADLY_EMBRACE | SIC: Deadly embrace of non-static inner class and thread local | 如果是一个静态内部类。实际上,在内部类和当前线程有死锁的可能。由于内部类不是静态的,它保留了对外部类的引用。如果线程包含对一个内部类实例的引用,那么内外实例的实例都可以被获取,这样就不具备垃圾会回收的资格。 |
| Correctness | SIO_SUPERFLUOUS_INSTANCEOF | SIO: Unnecessary type check done using instanceof operator | 在进行instanceof操作时进行没有必要的类型检查 |
| Correctness | STI_INTERRUPTED_ON_CURRENTTHREAD | STI: Unneeded use of currentThread() call, to call interrupted() | 此方法调用Thread.currentThread()调用,只需调用interrupted()方法。由于interrupted()是一个静态方法, Thread.interrupted()更简单易用。 |
| Correctness | STI_INTERRUPTED_ON_UNKNOWNTHREAD | STI: Static Thread.interrupted() method invoked on thread instance | 调用不是当前线程对象的Thread.interrupted()方法,由于interrupted()方法是静态的,interrupted方法将会调用一个和作者原计划不同的对象。 |
| Correctness | SE_METHOD_MUST_BE_PRIVATE | Se: Method must be private in order for serialization to work | 这个类实现了Serializable接口,并定义自定义序列化的方法/反序列化。但由于这种方法不能声明为private,将被序列化/反序列化的API忽略掉。 |
| Correctness | SE_READ_RESOLVE_IS_STATIC | Se: The readResolve method must not be declared as a static method. | 为使readResolve方法得到序列化机制的识别,不能作为一个静态方法来声明。 |
| Correctness | UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS | UMAC: Uncallable method defined in anonymous class | 在匿名类中定义了一个既没有覆写超类中方法也不能直接调用的方法。因为在其他类的方法不能直接引用匿名类声明的方法,似乎这种方法不能被调用,这种方法可能只是没有任何作用的代码,但也可能覆写超类中声明。 |
| Correctness | UR_UNINIT_READ | UR: Uninitialized read of field in constructor | 此构造方法中使用了一个尚未赋值的字段或属性。 String a; public SA() { String abc = a; System.out.println(abc); } |
| Correctness | DMI_INVOKING_TOSTRING_ON_ANONYMOUS_ARRAY | USELESS_STRING: Invocation of toString on an array | 该代码调用上匿名数组的toString()方法,产生的结果形如[@ 16f0472并没有实际的意义。考虑使用Arrays.toString方法来转换成可读的字符串,提供该数组的内容数组。例如: String[] a = { "a" }; System.out.println(a.toString()); //正确的使用为 System.out.println(Arrays.toString(a)); |
| Correctness | UWF_NULL_FIELD | UwF: Field only ever set to null | 字段的值总是为null值,所有读取该字段的值都为null。检查错误,如果它确实没有用就删除掉。 |
| Correctness | UWF_UNWRITTEN_FIELD | UwF: Unwritten field | 此字段是永远不会写入值。所有读取将返回默认值。检查错误(如果它被初始化?),如果它确实没有用就删除掉。 |
| Internationalization | DM_CONVERT_CASE | Dm: Consider using Locale parameterized version of invoked method | 使用平台默认的编码格式对字符串进行大小写转换,这可能导致国际字符的转换不当。使用以下方式对字符进行转换 String.toUpperCase( Locale l ) String.toLowerCase( Locale l ) |
| Malicious code vulnerability | DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED | DP: Classloaders should only be created inside doPrivileged block | 类加载器只能建立在特殊的方法体内 |
| Malicious code vulnerability | EI_EXPOSE_REP | EI: May expose internal representation by returning reference to mutable object | 返回一个易变对象引用并把它保存在对象字段中时会暴露对象内部的字段描述,如果接受不守信任的代码访问或者没有检查就去改变易变对象的会涉及对象的安全和其他重要属性的安全。返回一个对象的新副本,在很多情况下更好的办法。 |
| Malicious code vulnerability | EI_EXPOSE_REP2 | EI2: May expose internal representation by incorporating reference to mutable object | 此代码把外部可变对象引用存储到对象的内部表示。如果实例受到不信任的代码的访问和没有检查的变化危及对象和重要属性的安全。存储一个对象的副本,在很多情况下是更好的办法。 |
| Malicious code vulnerability | FI_PUBLIC_SHOULD_BE_PROTECTED | FI: Finalizer should be protected, not public | 一个类中的finalize()方法必须声明为protected,而不能为public类型 |
| Malicious code vulnerability | MS_EXPOSE_REP | MS: Public static method may expose internal representation by returning array | 一个public类型的静态方法返回一个数组,可能引用内部属性的暴露。任何代码调用此方法都可以自由修改底层数组。一个解决办法是返回一个数组的副本。 |
| Malicious code vulnerability | MS_FINAL_PKGPROTECT | MS: Field should be both final and package protected | 一个静态字段可能被恶意代码或另外一个包所改变的。字段可以放到protected包中也可以定义为final类型的以避免此问题。 |
| Malicious code vulnerability | MS_MUTABLE_ARRAY | MS: Field is a mutable array | 一个定义为final类型的静态字段引用一个数组时它可以被恶意代码或在另其他包中所使用。这些代码可以自由修改数组的内容。 |
| Malicious code vulnerability | MS_MUTABLE_HASHTABLE | MS: Field is a mutable Hashtable | 一个定义为final类型的静态字段引用一个Hashtable时可以被恶意代码或者在其他包中被调用,这些方法可以修改Hashtable的值。 |
| Malicious code vulnerability | MS_OOI_PKGPROTECT | MS: Field should be moved out of an interface and made package protected | 将域尽量不要定义在接口中,并声明为包保护在接口中定义了一个final类型的静态字段,如数组或哈希表等易变对象。这些对象可以被恶意代码或者在其他包中被调用,为了解决这个问题,需要把它定义到一个具体的实体类中并且声明为保护类型以避免这种错误。 |
| Malicious code vulnerability | MS_PKGPROTECT | MS: Field should be package protected | 一个静态字段是可以改变的恶意代码或其他的包访问修改。可以把这种类型的字段声明为final类型的以防止这种错误。 |
| Multithreaded correctness | DM_MONITOR_WAIT_ON_CONDITION | Dm: Monitor wait() called on Condition | 方法中以java.util.concurrent.locks.Condition对象调用wait()。等待一个条件发生时应该使用在Condition接口中定义的await()方法。 |
| Multithreaded correctness | DM_USELESS_THREAD | Dm: A thread was created using the default empty run method | 这个方法没有通过run方法或者具体声明Thread类,也没有通过一个Runnable对象去定义一个线程,而这个线程出来浪费资源却什么也没有去做。 |
| Multithreaded correctness | ESync_EMPTY_SYNC | ESync: Empty synchronized block | 该代码包含一个空的同步块:synchronized() {} |
| Multithreaded correctness | IS2_INCONSISTENT_SYNC | IS: Inconsistent synchronization | 不合理的同步 |
| Multithreaded correctness | IS_FIELD_NOT_GUARDED | IS: Field not guarded against concurrent access | 域不是良好的同步访问---此字段被标注为net.jcip.annotations.GuardedBy,但可以在某种程度上违反注释而去访问 |
| Multithreaded correctness | JLM_JSR166_LOCK_MONITORENTER | JLM: Synchronization performed on Lock | 实现java.util.concurrent.locks.Lock的对象调用了同步的方法。应该这样处理,对象被锁定/解锁时使用acquire()/ release()方法而不是使用同步的方法。 |
| Multithreaded correctness | LI_LAZY_INIT_STATIC | LI: Incorrect lazy initialization of static field | 静态域不正确的延迟初始化-- 这种方法包含了一个不同步延迟初始化的非volatile静态字段。因为编译器或处理器可能会重新排列指令,如果该方法可以被多个线程调用,线程不能保证看到一个完全初始化的对象。你可以让字段可变来解决此问题 |
| Multithreaded correctness | LI_LAZY_INIT_UPDATE_STATIC | LI: Incorrect lazy initialization and update of static field | 这种方法包含一个不同步延迟初始化的静态字段。之后为字段赋值,对象存储到该位置后进一步更新或访问。字段后尽快让其他线程能够访问。如果该方法的进一步访问该字段为初始化对象提供服务,然后你有一个非常严重的多线程bug,除非别的东西阻止任何其他线程访问存储的对象,直到它完全初始化。即使你有信心,该方法是永远不会被多个线程调用时,在它的值还没有被充分初始化或移动,不把它设定为static字段时它可能会更好。 |
| Multithreaded correctness | ML_SYNC_ON_UPDATED_FIELD | ML: Method synchronizes on an updated field | 对象获取一个可变字段时进行同步。这是没有意义的,因为不同的线程可以在不同的对象同步。 |
| Multithreaded correctness | MSF_MUTABLE_SERVLET_FIELD | MSF: Mutable servlet field | 一个web服务一般只能创建一个servlet或者jsp的实例(例如:treates是一个单利类),它会被多个线程调用这个实例的方法服务于多个同时的请求。因此使用易变的字段属性产生竞争的情况。 |
| Multithreaded correctness | MWN_MISMATCHED_NOTIFY | MWN: Mismatched notify() | 此方法调用Object.notify()或Object.notifyAll()而没有获取到该对象的对象锁。调用notify()或notifyAll()而没有持有该对象的对象锁,将导致IllegalMonitorStateException异常。 |
| Multithreaded correctness | MWN_MISMATCHED_WAIT | MWN: Mismatched wait() | 此方法调用Object.wait()而没有获取到该对象的对象锁。调用wait()而没有持有该对象的对象锁,将导致IllegalMonitorStateException异常。 |
| Multithreaded correctness | NP_SYNC_AND_NULL_CHECK_FIELD | NP: Synchronize and null check on the same field. | 如果代码块是同步的,那么久不可能为空。如果是空,同步时就会抛出NullPointerException异常。最好是在另一个代码块中进行同步。 |
| Multithreaded correctness | NO_NOTIFY_NOT_NOTIFYALL | No: Using notify() rather than notifyAll() | 调用notify()而不是notifyAll()方法。 Java的监控器通常用于多个条件。调用notify()只唤醒一个线程,这意味着该线程被唤醒只是满足的当前的唯一条件。 |
| Multithreaded correctness | RS_READOBJECT_SYNC | RS: Class's readObject() method is synchronized | 序列化类中定义了同步的readObject()。通过定义,反序列化创建的对象只有一个线程可以访问,因此没有必要的readObject()进行同步。如果的readObject()方法本身造成对象对另一个线程可见,那么这本身就是不好的编码方式。 |
| Multithreaded correctness | RU_INVOKE_RUN | Ru: Invokes run on a thread (did you mean to start it instead?) | 这种方法显式调用一个对象的run()。一般来说,类是实现Runnable接口的,因为在一个新的线程他们将有自己的run()方法,在这种情况下Thread.start()方法调用是正确的。 |
| Multithreaded correctness | SC_START_IN_CTOR | SC: Constructor invokes Thread.start() | 在构造函数中启动一个线程。如果类曾经被子类扩展过,那么这很可能是错的,因为线程将在子类构造之前开始启动。 |
| Multithreaded correctness | SP_SPIN_ON_FIELD | SP: Method spins on field | 方法无限循环读取一个字段。编译器可合法悬挂宣读循环,变成一个无限循环的代码。这个类应该改变,所以使用适当的同步(包括等待和通知要求) |
| Multithreaded correctness | STCAL_INVOKE_ON_STATIC_CALENDAR_INSTANCE | STCAL: Call to static Calendar | 即使JavaDoc对此不包含暗示,而Calendars本身在多线程中使用就是不安全的。探测器发现当调用Calendars的实例时将会获得一个静态对象。Calendar rightNow = Calendar.getInstance(); |
| Multithreaded correctness | STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE | STCAL: Call to static DateFormat | 在官方的JavaDoc,DateFormats多线程使用本事就是不安全的。探测器发现调用一个DateFormat的实例将会获得一个静态对象。 myString = DateFormat.getDateInstance().format(myDate); |
| Multithreaded correctness | STCAL_STATIC_CALENDAR_INSTANCE | STCAL: Static Calendar field | Calendar在多线程中本身就是不安全的,如果在线程范围中共享一个Calendarde 实例而不使用一个同步的方法在应用中就会出现一些奇怪的行为。在sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate()中会抛出ArrayIndexOutOfBoundsExceptions or IndexOutOfBoundsExceptions异常。 |
| Multithreaded correctness | STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE | STCAL: Static DateFormat | DateFormat 在多线程中本身就是不安全的,如果在线程范围中共享一个DateFormat的实例而不使用一个同步的方法在应用中就会出现一些奇怪的行为。 |
| Multithreaded correctness | SWL_SLEEP_WITH_LOCK_HELD | SWL: Method calls Thread.sleep() with a lock held | 当持有对象时调用Thread.sleep()。这可能会导致很差的性能和可扩展性,或陷入死锁,因为其他线程可能正在等待获得锁。调用wait()是一个更好的主意,释放对象的持有以允许其他线程运行。 |
| Multithreaded correctness | UG_SYNC_SET_UNSYNC_GET | UG: Unsynchronized get method, synchronized set method | 这个类包含类似命名的get和set方法。在set方法是同步方法和get方法是非同步方法。这可能会导致在运行时的不正确行为,因为调用的get方法不一定返回对象一致状态。 GET方法应该同步。 |
| Multithreaded correctness | UL_UNRELEASED_LOCK | UL: Method does not release lock on all paths | 方法获得了当前的对象所,但是在方法中始终没有释放它。一个正确的示例如下: Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); } |
| Multithreaded correctness | UL_UNRELEASED_LOCK_EXCEPTION_PATH | UL: Method does not release lock on all exception paths | 方法获得了当前的对象所,但是在所有的异常处理中始终没有释放它。一个正确的示例如下: Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); } |
| Multithreaded correctness | UW_UNCOND_WAIT | UW: Unconditional wait | 方法中包含调用java.lang.Object.wait(),而却没有放到条件流程控制中。该代码应确认条件尚未满足之前等待;先前任何通知将被忽略。 |
| Multithreaded correctness | VO_VOLATILE_REFERENCE_TO_ARRAY | VO: A volatile reference to an array doesn't treat the array elements as volatile | 声明一个变量引用数组,这可能不是你想要的。如果一个变量引用数组,那么对引用数组的读和写都是不安全的,但是数组元素不是变量。取得数组的变量值你可以使用java.util.concurrent包中的数组的原子性特性 |
| Multithreaded correctness | WS_WRITEOBJECT_SYNC | WS: Class's writeObject() method is synchronized but nothing else is | 这个类有一个writeObject()方法是同步的,但是这个类中没有其他的同步方法。 |
| Multithreaded correctness | WA_AWAIT_NOT_IN_LOOP | Wa: Condition.await() not in loop | 方法没有在循环中调用java.util.concurrent.await()。如果对象是用于多种条件,打算调用wait()方法的条件可能不是实际发生的。 |
| Multithreaded correctness | WA_NOT_IN_LOOP | Wa: Wait not in loop | 这种方法包含调用java.lang.Object.wait(),而这并不是一个循环。如果监视器用于多个条件,打算调用wait()方法的条件可能不是实际发生的。 |
| Performance | BX_BOXING_IMMEDIATELY_UNBOXED | Bx: Primitive value is boxed and then immediately unboxed | 对原始值进行装箱,然后立即取消装箱。这可能是在一个未要求装箱的地方进行了手动装箱,从而迫使编译器进行立即撤消装箱的操作 |
| Performance | BX_BOXING_IMMEDIATELY_UNBOXED_TO_PERFORM_COERCION | Bx: Primitive value is boxed then unboxed to perform primitive coercion | 对原始值进行装箱然后立即把它强制转换为另外一种原始类型。例如: new Double(d).intValue()应该直接进行强制转换例如:(int) d |
| Performance | BX_UNBOXED_AND_COERCED_FOR_TERNARY_OPERATOR | Bx: Primitive value is unboxed and coerced for ternary operator | 在三元运算符操作时如果没有对值进行封装或者类型转换。例如:b ? e1 : e2 |
| Performance | DM_FP_NUMBER_CTOR | Bx: Method invokes inefficient floating-point Number constructor; use static valueOf instead | 使用new Double(double)方法总是会创建一个新的对象,然而使用Double.valueOf(double)方法可以把值保存在编辑器或者class library、JVM中。使用存储值的方式来避免对象的分配可以或得更好的代码性能除非类必须符合Java 1.5以前的JVM,否则请使用自动装箱或valueOf()方法创建Double和Float实例。 |
| Performance | DM_NUMBER_CTOR | Bx: Method invokes inefficient Number constructor; use static valueOf instead | 使用new Integer(int)方法总是会创建一个新的对象,然而使用Integer.valueOf(int)方法可以把值保存在编辑器或者class library、JVM中。使用存储值的方式来避免对象的分配可以或得更好的代码性能除非类必须符合Java 1.5以前的JVM,否则请使用自动装箱或valueOf()方法创建Long, Integer, Short, Character, Byte实例。 |
| Performance | DMI_BLOCKING_METHODS_ON_URL | Dm: The equals and hashCode methods of URL are blocking | 使用equals和hashCode方法来对url进行资源标识符解析时会引起堵塞。考虑使用java.net.URI来代替。 |
| Performance | DMI_COLLECTION_OF_URLS | Dm: Maps and sets of URLs can be performance hogs | 方法或者字段使用url的map/set集合。因为equals方法或者hashCode方法来进行资源标识符解析时都会引起堵塞。考虑使用java.net.URI来代替。 |
| Performance | DM_BOOLEAN_CTOR | Dm: Method invokes inefficient Boolean constructor; use Boolean.valueOf(...) instead | 使用new方法创建一个java.lang.Boolean类型能够的实例对象是浪费空间的,因为Boolean对象是不可变的而且只有两个有用的值。使用Boolean.valueOf()或者Java1.5中的自动装箱功能来创建一个Boolean实例。 |
| Performance | DM_GC | Dm: Explicit garbage collection; extremely dubious except in benchmarking code | 在代码中显式的调用垃圾回收命名,这样做并不能起作用。在过去,有人在关闭操作或者finalize方法中调用垃圾回收方法导致了很多的性能浪费。这样大规模回收对象时会造成处理器运行缓慢。 |
| Performance | DM_NEXTINT_VIA_NEXTDOUBLE | Dm: Use the nextInt method of Random rather than nextDouble to generate a random integer | 如果r是一个java.util.Random对象,你可以使r.nextInt(n)生成一个0到n-1之前的随机数,而不是使用(int)(r.nextDouble() * n) |
| Performance | DM_STRING_CTOR | Dm: Method invokes inefficient new String(String) constructor | 使用java.lang.String(String)构造函数会浪费内存因为这种构造方式和String作为参数在功能上容易混乱。只是使用String直接作为参数的形式 |
| Performance | DM_STRING_TOSTRING | Dm: Method invokes toString() method on a String | 调用String.toString()是多余的操作,只要使用String就可以了。 |
| Performance | DM_STRING_VOID_CTOR | Dm: Method invokes inefficient new String() constructor | 使用没有参数的构造方法去创建新的String对象是浪费内存空间的,因为这样创建会和空字符串""混淆。Java中保证完成相同的构造方法会产生描绘相同的String对象。所以你只要使用空字符串来创建就可以了。 |
| Performance | ITA_INEFFICIENT_TO_ARRAY | ITA: Method uses toArray() with zero-length array argument | 当使用集合的toArray()方法时使用数组长度为0的数组作为参数。比这更有效的一种方法是myCollection.toArray(new Foo[myCollection.size()]),如果数组的长度足够大就可以直接把集合中的内容包装到数组中直接返回从而避免了第二次创建一个新的数组来存放集合中值。 |
| Performance | SS_SHOULD_BE_STATIC | SS: Unread field: should this field be static? | 类中所包含的final属性字段在编译器中初始化为静态的值。考虑在定义时就把它定义为static类型的。 |
| Performance | UPM_UNCALLED_PRIVATE_METHOD | UPM: Private method is never called | 定义为Private类型方法从未被调用,应该被删除。 |
| Performance | URF_UNREAD_FIELD | UrF: Unread field | 类中定义的属性从未被调用,建议删除。 |
| Performance | UUF_UNUSED_FIELD | UuF: Unused field | 类中定义的属性从未被使用,建议删除。 |
| Performance | WMI_WRONG_MAP_ITERATOR | WMI: Inefficient use of keySet iterator instead of entrySet iterator | 当方法中接受一个Map类型的参数时,使用keySet的迭代器比使用entrySet的迭代器效率要高。 |
| Security | DMI_CONSTANT_DB_PASSWORD | Dm: Hardcoded constant database password | 代码中创建DB的密码时采用了写死的密码。 |
| Security | DMI_EMPTY_DB_PASSWORD | Dm: Empty database password | 创建数据库连接时没有为数据库设置密码,这会使数据库没有必要的保护。 |
| Security | HRS_REQUEST_PARAMETER_TO_COOKIE | HRS: HTTP cookie formed from untrusted input | 此代码使用不受信任的HTTP参数构造一个HTTP Cookie。 |
| Security | HRS_REQUEST_PARAMETER_TO_HTTP_HEADER | HRS: HTTP Response splitting vulnerability | 在代码中直接把一个HTTP的参数写入一个HTTP头文件中,它为HTTP的响应暴露了漏洞。 |
| Security | SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE | SQL: Nonconstant string passed to execute or addBatch method on an SQL statement | 该方法以字符串的形式来调用SQLstatement的execute方法,它似乎是动态生成SQL语句的方法。这会更容易受到SQL注入攻击。 |
| Security | XSS_REQUEST_PARAMETER_TO_JSP_WRITER | XSS: JSP reflected cross site scripting vulnerability | 在代码中在JSP输出中直接写入一个HTTP参数,这会造成一个跨站点的脚本漏洞。 |
| Security | XSS_REQUEST_PARAMETER_TO_SEND_ERROR | XSS: Servlet reflected cross site scripting vulnerability in error page | 在代码中在Servlet输出中直接写入一个HTTP参数,这会造成一个跨站点的脚本漏洞。 |
| Security | XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER | XSS: Servlet reflected cross site scripting vulnerability | 代码直接写入参数的HTTP服务器错误页(使用HttpServletResponse.sendError)。表达了类似的不受信任的输入会引起跨站点脚本漏洞。 |
| Dodgy code | BC_BAD_CAST_TO_ABSTRACT_COLLECTION | BC: Questionable cast to abstract collection | 在代码投把一个集合强制类型转换为一个抽象的集合(如list,set或map)。保证该对象类型和将要转换的类型是一致的。如果你只是想要便利一个集合,那么你就不必将它转换为Set或List。 |
| Dodgy code | BC_BAD_CAST_TO_CONCRETE_COLLECTION | BC: Questionable cast to concrete collection | 代码把抽象的集合(如List,Set,或Collection)强制转换为具体落实类型(如一个ArrayList或HashSet)。这可能不正确,也可能使您的代码很脆弱,因为它使得难以在今后的切换指向其他具体实现。除非你有特别理由这样做,否则只需要使用抽象的集合类。 |
| Dodgy code | BC_UNCONFIRMED_CAST | BC: Unchecked/unconfirmed cast | 强制类型转换操作没有经过验证,而且不是所有的此种类型装换过的类都可以再强制类型转换为原类型。在代码中需要进行逻辑判断以保证可以进行这样的操作。 |
| Dodgy code | BC_VACUOUS_INSTANCEOF | BC: instanceof will always return true | instanceof测试将始终返回真(除非被测试的值为空)。虽然这是安全,确保它是不是说明一些误解或其他一些逻辑错误。如果你真的想测试是空的价值,也许会更清楚这样做的更好空试验,而不是一个instanceof测试。 |
| Dodgy code | ICAST_QUESTIONABLE_UNSIGNED_RIGHT_SHIFT | BSHIFT: Unsigned right shift cast to short/byte | 无符号数右移后进行转换为short或者byte类型时可能会丢弃掉高位的值,这样的结果就是有符合数和无符号数无法区分(这取决于移位大小) |
| Dodgy code | CI_CONFUSED_INHERITANCE | CI: Class is final but declares protected field | 这个类被声明为final的,而是字段属性却声明为保护类型的。由于是final类,它不能再被继承,而再声明为保护类型的很容易造成混淆。为了从外部能正确的使用它应该把它们声明为private或者public类型。 |
| Dodgy code | DB_DUPLICATE_BRANCHES | DB: Method uses the same code for two branches | 此方法使用相同的代码,以实现两个有条件的分支。检查以确保这是不是一个编码错误。 |
| Dodgy code | DB_DUPLICATE_SWITCH_CLAUSES | DB: Method uses the same code for two switch clauses | 他的方法使用相同的代码来实现两个switch的声明条款。这可能是重复代码的情况,但可能也显示出编码的错误。 |
| Dodgy code | DLS_DEAD_LOCAL_STORE | DLS: Dead store to local variable | 该指令为局部变量赋值,但在其后的没有对她做任何使用。通常,这表明一个错误,因为值从未使用过。 |
| Dodgy code | DLS_DEAD_LOCAL_STORE_IN_RETURN | DLS: Useless assignment in return statement | 本声明把一个局部变量放到方法的返回语句中。这对于方法中局部变量来说是没有意思的。 |
| Dodgy code | DLS_DEAD_LOCAL_STORE_OF_NULL | DLS: Dead store of null to local variable | 把一个本地变量赋值为null值,并且再也没有对这个变量做任何的操作。这样可能是为了垃圾回收,而是Java SE 6.0,这已不再需要。 |
| Dodgy code | DMI_HARDCODED_ABSOLUTE_FILENAME | DMI: Code contains a hard coded reference to an absolute pathname | 此代码包含文件对象为一个绝对路径名 |
| Dodgy code | DMI_NONSERIALIZABLE_OBJECT_WRITTEN | DMI: Non serializable object written to ObjectOutput | 代码中让一个非序列化的对象出现在ObjectOutput.writeObject()方法中,这样会引起一个错误。 |
| Dodgy code | DMI_USELESS_SUBSTRING | DMI: Invocation of substring(0), which returns the original value | 此代码调用了subString(0)方法,它将返回原来的值。 |
| Dodgy code | EQ_DOESNT_OVERRIDE_EQUALS | Eq: Class doesn't override equals in superclass | 子类定义了一个新的equals方法但是却不是覆写了父类本省的equals()方法。 |
| Dodgy code | FE_FLOATING_POINT_EQUALITY | FE: Test for floating point equality | 此操作比较两个浮点值是否相等。由于浮点运算可能会涉及到舍入,计算float和double值可能不准确。如果要求值必须准确,如货币值,可以考虑使用固定精度类型,如BigDecimal类型的值来比较 |
| Dodgy code | VA_FORMAT_STRING_BAD_CONVERSION_TO_BOOLEAN | FS: Non-Boolean argument formatted using %b format specifier | 使用%b去格式化Boolean类型的值不正确的但是它不会抛出异常,任何非空的值都会输出true,任何为空的值都会输出false |
| Dodgy code | IC_INIT_CIRCULARITY | IC: Initialization circularity | 在引用两个相互调用为环状static方法去初始化一个实例时是错误的。 |
| Dodgy code | ICAST_IDIV_CAST_TO_DOUBLE | ICAST: Integral division result cast to double or float | 整形数除法强制转换为double或者float类型。 int x = 2; int y = 5; // Wrong: yields result 0.0 double value1 = x / y; // Right: yields result 0.4 double value2 = x / (double) y; |
| Dodgy code | IM_AVERAGE_COMPUTATION_COULD_OVERFLOW | IM: Computation of average could overflow | 代码中使用x % 2 == 1的方法去验证运算是否存在余数的情况,但是如果出现负数的情况就不起作用了。使用x & 1 == 1, or x % 2 != 0来代替 |
| Dodgy code | INT_VACUOUS_COMPARISON | INT: Vacuous comparison of integer value | 整形数进行比较结果总是不变。例如:x <= Integer.MAX_VALUE |
| Dodgy code | MTIA_SUSPECT_SERVLET_INSTANCE_FIELD | MTIA: Class extends Servlet class and uses instance variables | 这个类扩展从Servlet类,并使用实例的成员变量。由于只有一个Servlet类的实例,并在多线程方式使用,这种模式有可能存在问题。考虑只使用方法的局部变量。 |
| Dodgy code | MTIA_SUSPECT_STRUTS_INSTANCE_FIELD | MTIA: Class extends Struts Action class and uses instance variables | 类扩展自Struts的Action类并使用这个实例的成员变量,因为在Struts框架中只存在一个Action实例对象并且使用在多线程的情况下很可能会出现问题。 |
| Dodgy code | NP_DEREFERENCE_OF_READLINE_VALUE | NP: Dereference of the result of readLine() without nullcheck | 对readLine()的结果值没有进行判空操作就去重新赋值,这样的操作可以会抛出空指针异常。 |
| Dodgy code | NP_IMMEDIATE_DEREFERENCE_OF_READLINE | NP: Immediate dereference of the result of readLine() | 对readLine()的结果立即赋值,这样的操作可以会抛出空指针异常。 |
| Dodgy code | NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE | NP: Possible null pointer dereference due to return value of called method | 方法的返回值没有进行是否为空的检查就重新赋值,这样可能会出现空指针异常。 |
| Dodgy code | NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE | NP: Parameter must be non-null but is marked as nullable | 参数值在任何情况下都不能为空,但是有明确的注释它可以为空。 |
| Dodgy code | NS_DANGEROUS_NON_SHORT_CIRCUIT | NS: Potentially dangerous use of non-short-circuit logic | 代码中使用(& or |)代替(&& or ||)操作,这会造成潜在的危险。 |
| Dodgy code | NS_NON_SHORT_CIRCUIT | NS: Questionable use of non-short-circuit logic | 代码中使用(& or |)代替(&& or ||)操作,会引起不安全的操作 |
| Dodgy code | PZLA_PREFER_ZERO_LENGTH_ARRAYS | PZLA: Consider returning a zero length array rather than null | 考虑返回一个零长度的数组,而不是null值 |
| Dodgy code | QF_QUESTIONABLE_FOR_LOOP | QF: Complicated, subtle or wrong increment in for-loop | 确定这个循环是正确的变量递增,看起来,另一个变量被初始化,检查的循环。这是由于for循环中太复杂的定义造成的。 |
| Dodgy code | RCN_REDUNDANT_COMPARISON_OF_NULL_AND_NONNULL_VALUE | RCN: Redundant comparison of non-null value to null | 方法中包含一个不能为空的赋值还包含一个可以为空的赋值。冗余比较非空值为空。 |
| Dodgy code | RCN_REDUNDANT_COMPARISON_TWO_NULL_VALUES | RCN: Redundant comparison of two null values | 方法中对两个null值进行比较 |
| Dodgy code | RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE | RCN: Redundant nullcheck of value known to be non-null | 方法中对不为空的值进行为空的判断。 |
| Dodgy code | REC_CATCH_EXCEPTION | REC: Exception is caught when Exception is not thrown | 在try/catch块中捕获异常,但是异常没有在try语句中抛出而RuntimeException又没有明确的被捕获 |
| Dodgy code | RI_REDUNDANT_INTERFACES | RI: Class implements same interface as superclass | 子类和父类都实现了同一个接口,这种定义是多余的。 |
| Dodgy code | RV_DONT_JUST_NULL_CHECK_READLINE | RV: Method discards result of readLine after checking if it is non-null | readLine方法的结果不为空时被抛弃 |
| Dodgy code | RV_REM_OF_RANDOM_INT | RV: Remainder of 32-bit signed random integer | 此代码生成一个随机的符号整数,然后计算另一个值的。由于随机数可以是负数,所以其余操作的结果也可以是负面的。考虑使用Random.nextInt(int)方法代替。 |
| Dodgy code | SA_FIELD_DOUBLE_ASSIGNMENT | SA: Double assignment of field | 方法中的字段包含了双重任务,例如: int x; public void foo() { x = x = 17; } 这种为变量赋值是无用的,并可能表明一个逻辑错误或拼写错误。 |
| Dodgy code | SA_LOCAL_DOUBLE_ASSIGNMENT | SA: Double assignment of local variable | 为一个局部变量两次赋值,这样是没有意义的。例如: public void foo() { int x,y; x = x = 17; } |
| Dodgy code | SA_LOCAL_SELF_ASSIGNMENT | SA: Self assignment of local variable | 局部变量使用自身给自己赋值 public void foo() { int x = 3; x = x; } |
| Dodgy code | SF_SWITCH_FALLTHROUGH | SF: Switch statement found where one case falls through to the next case | Switch语句中一个分支执行后又执行了下一个分支。通常case后面要跟break 或者return语句来跳出。 |
| Dodgy code | SF_SWITCH_NO_DEFAULT | SF: Switch statement found where default case is missing | Switch没有默认情况下执行的case语句。 |
| Dodgy code | SE_PRIVATE_READ_RESOLVE_NOT_INHERITED | Se: Private readResolve method not inherited by subclasses | 声明为private的序列化方法被子类继承 |
| Dodgy code | UCF_USELESS_CONTROL_FLOW | UCF: Useless control flow | 没有任何作用的条件语句。 if (argv.length == 0) { // TODO: handle this case } |
| Dodgy code | UCF_USELESS_CONTROL_FLOW_NEXT_LINE | UCF: Useless control flow to next line | 无效的条件控制语句,注意if (argv.length == 1);以";"结尾,下面的语句无论是否满足都会运行。 if (argv.length == 1); System.out.println("Hello, " + argv[0]); |
| Dodgy code | XFB_XML_FACTORY_BYPASS | XFB: Method directly allocates a specific implementation of xml interfaces | 方法自定义了一种XML接口的实现类。最好是使用官方提供的工厂类来创建这些对象,以便可以在运行期中改变。例如: javax.xml.parsers.DocumentBuilderFactory javax.xml.parsers.SAXParserFactory javax.xml.transform.TransformerFactory org.w3c.dom.Document.createXXXX |