FindBugs 规则整理:CORRECTNESS
UWF_NULL_FIELD
- 翻译
Field only ever set to null: …
All writes to this field are of the constant value null, and thus all reads of the field will return null. Check for errors, or remove it if it is useless.
某个域的值一直都为null,导致所有读取到的该域的值也都是null,检查该域是否存在异常,或者移除这个无用的域 - 原因
在某个类里面我们定义了一个私有的成员变量,但是这个成员变量在实例范围内没有得到任何的初始化(采用默认的构造方法),始终为null,所以在实例范围内使用该成员变量时,如果不先对其进行初始化操作或者无意识的行为忘了初始化操作,那肯定是要报空指针异常 - 解决方案
对该变量进行正确的赋值或者移除
RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE
- 翻译
Nullcheck of form at line .. of value previously dereferenced in …
A value is checked here to see whether it is null, but this value can’t be null because it was previously dereferenced and if it were null a null pointer exception would have occurred at the earlier dereference. Essentially, this code and the previous dereference disagree as to whether this value is allowed to be null. Either the check is redundant or the previous dereference is erroneous.
某个值虽然在某处有被判断是否为null,但是这个值在该处并不可以为null,因为这个值被提前引用了,如果他有可能是null,在被引用的时候就会产生空指针异常,所以这里的判断也就是多余的,而在该判断之前的引用也可能是错误的。 - 原因
判断某个值是否为null的时机错误 - 解决方案
修改判断时机等,视具体情况而定
NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH
- 翻译
.. is null guaranteed to be dereferenced in … 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).
在某个异常发生时候某个值将会被置为null,而该null值会被引用 - 原因
比如我们在finally中调用了一个在异常发生时则无法正常初始化的对象,这时候就可能产生空指针等异常 - 解决方案
判断每个分支中所引用的值在各种情况下是否符合预期,避免产生异常
NP_NULL_ON_SOME_PATH_EXCEPTION
- 翻译
Possible null pointer dereference of .. in … on exception path
A reference value which is null on some exception control path is dereferenced here. This may lead to a NullPointerException when the code is executed. Note that because FindBugs currently does not prune infeasible exception paths, this may be a false warning.
Also note that FindBugs considers the default case of a switch statement to be an exception path, since the default case is often infeasible.
因为某些异常路径的发生导致部分对象无法正常初始化,但后续该对象仍会被调用从而产生空指针异常。由于FindBgus无法去除不会执行的异常路径,所以这也可能是一个错误的警告。 - 原因
同NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH - 解决方案
同NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH
EC_UNRELATED_TYPES
- 翻译
Call to String.equals(Double) in …
This method calls equals(Object) on two references of different class types with no common subclasses. Therefore, the objects being compared are unlikely to be members of the same class at runtime (unless some application classes were not analyzed, or dynamic class loading can occur at runtime). According to the contract of equals(), objects of different classes should always compare as unequal; therefore, according to the contract defined by java.lang.Object.equals(Object), the result of this comparison will always be false at runtime.
两个不同的类的实例通过equals方法,通常情况下都会判断为非相同对象,其返回值也将始终为false。 - 原因
如第一行所说,调用string的equals方法比较double类型,永远都会返回false,如果把这个作为逻辑判断是没有意义的 - 解决方案
去除这种无意义的判断
DMI_INVOKING_TOSTRING_ON_ARRAY
- 翻译
Invocation of toString on … in …
The code invokes toString on an array, which will generate a fairly useless result such as [C@16f0472. Consider using Arrays.toString to convert the array into a readable String that gives the contents of the array. See Programming Puzzlers, chapter 3, puzzle 12.
在一个array数组上调用toString将返回如C@16f0472等无意义的结果,可以使用Arrays.toString方法来将数组转换为可读的字符串。 - 原因
大多数这个问题出在直接打印某个数组是否为空,而FindBugs不知道此处只是log日志,这种直接打印的方法会默认调用对象的toString方法,输出对象的内存地址,也不排除其他情况。 - 解决方案
如果是日志可以选择不处理或者隐藏日志,其他情况则视具体情况而定。
UWF_UNWRITTEN_FIELD
- 翻译
Unwritten field: …
This field is never written. All reads of it will return the default value. Check for errors (should it have been initialized?), or remove it if it is useless.
某个域没有被赋值过,所有对这个变量的读取都会获得默认值,检查该变量是否存在异常,或者移除这个无用的变量 - 原因
变量只有默认值,后续没有再进行任何赋值过 - 解决方案
判断是否存在使用上的异常,或者抽取为final常量等,视情况而定
IL_INFINITE_RECURSIVE_LOOP
- 翻译
There is an apparent infinite recursive loop in …
This method unconditionally invokes itself. This would seem to indicate an infinite recursive loop that will result in a stack overflow.
在某处存在死循环。 - 原因
如无跳出条件的递归等造成的死循环 - 解决方案
修改出现死循环的代码
FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER
Doomed test for equality to NaN
This code checks to see if a floating point value is equal to the special Not A Number value (e.g., if (x == Double.NaN)). However, because of the special semantics of NaN, no value is equal to Nan, including NaN. Thus, x == Double.NaN always evaluates to false. To check to see if a value contained in x is the special Not A Number value, use Double.isNaN(x) (or Float.isNaN(x) if x is floating point precision).
判断是否与NaN相等,但是并不会有值与NaN相等,所以这个判断永远返回false
BC_IMPOSSIBLE_CAST
Impossible cast
不可能的类转换,执行时会抛出ClassCastException
BC_IMPOSSIBLE_DOWNCAST
Impossible downcast
父类在向下进行类型转换时抛出ClassCastException
BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY
- 翻译
This code is casting the result of calling toArray() on a collection to a type more specific than Object[], as in:
String[] getAsArray(Collectionc) {
return (String[]) c.toArray();
}
This will usually fail by throwing a ClassCastException. The toArray() of almost all collections return an Object[]. They can’t really do anything else, since the Collection object has no reference to the declared generic type of the collection.
The correct way to do get an array of a specific type from a collection is to use c.toArray(new String[]); or c.toArray(new String[c.size()]); (the latter is slightly more efficient).
某段代码调用Collection.toArray方法获得一组对Object数组更具体的对象数组,这通常会导致ClassCastException。toArray方法大多数集合会返回Object[],它们不能做其他实际的事情,因为集合对象没有声明泛型类型的引用 - 原因
集合转换为数组元素时发生的类转换错误。 - 解决方案
使用Collection.toArray(new String[]) 或者Collection.toArray(new String[Collection.size()]) 转换
BC_IMPOSSIBLE_INSTANCEOF
Instanceof will always return false
采用instaneof方法进行比较时总是返回false。前提是保证它不是由于某些逻辑错误造成的。
BIT_AND
Incompatible bit masks
错误的使用&位操作符,例如(e & C)
BIT_AND_ZZ
Check to see if ((…) & 0) == 0
检查恒等的逻辑错误
BIT_IOR
Incompatible bit masks
错误的使用|位操作符,例如(e | C)
BIT_SIGNED_CHECK_HIGH_BIT
Check for sign of bitwise operation
检查逻辑运算符操作返回的标识。例如((event.detail & SWT.SELECTED) > 0),建议采用 !=0 代替 >0
BOA_BADLY_OVERRIDDEN_ADAPTER
Class overrides a method implemented in super class Adapter wrongly
子类错误的覆写父类中用于适配监听其他事件的方法,从而导致当触发条件发生时不能被监听者调用
BX_UNBOXED_AND_COERCED_FOR_TERNARY_OPERATOR
Primitive value is unboxed and coerced for ternary operator
在三元运算符操作时如果没有对值进行封装或者类型转换。例如:b ? e1 : e2
DLS_DEAD_STORE_OF_CLASS_LITERAL
Dead store of class literal
以类的字面名称方式为一个字段赋值后再也没有去使用它,在1.4jdk中它会自动调用静态的初始化方法,而在jdk1.5中却不会去执行。
DLS_OVERWRITTEN_INCREMENT
Overwritten increment
覆写增量增加错误i = i++
DMI_BAD_MONTH
Bad constant value for month
表示月份的错误常量值
DMI_COLLECTIONS_SHOULD_NOT_CONTAIN_THEMSELVES
Collections should not contain themselves
集合不应该包含他们自己本身。
DMI_INVOKING_HASHCODE_ON_ARRAY
Invocation of hashCode on an array
在数组上调用了hashCode
DMI_LONG_BITS_TO_DOUBLE_INVOKED_ON_INT
Double.longBitsToDouble invoked on an int
在int上调用了Double.longBitsToDouble
DMI_VACUOUS_SELF_COLLECTION_CALL
Vacuous call to collections
集合的调用不能被感知。例如c.containsAll(c)总是返回true,而c.retainAll(c)的返回值不能被感知。
DMI_ANNOTATION_IS_NOT_VISIBLE_TO_REFLECTION
Can’t use reflection to check for presence of annotation without runtime retention
不能使用反射检测没有标记为runtime rentention的注解的存在
DMI_VACUOUS_CALL_TO_EASYMOCK_METHOD
Useless/vacuous call to EasyMock method
EasyMock方法的无用/空调用
EC_ARRAY_AND_NONARRAY
equals() used to compare array and nonarray
数组对象使用equals方法和非数组对象进行比较。即使比较的双方都是数组对象也不应该使用equals方法,而应该比较它们的内容是否相等使用java.util.Arrays.equals(Object[], Object[]);
使用指针比较不同的类型
EC_INCOMPATIBLE_ARRAY_COMPARE
equals(…) used to compare incompatible arrays
使用equls方法去比较类型不相同的数组。例如:String[] and StringBuffer[], or String[] and int[]
EC_NULL_ARG
Call to equals() with null argument
调用equals的对象为null
EC_UNRELATED_CLASS_AND_INTERFACE
Call to equals() comparing unrelated class and interface
使用equals方法比较不相关的类和接口
EC_UNRELATED_INTERFACES
Call to equals() comparing different interface types
调用equals方法比较不同类型的接口
EC_UNRELATED_TYPES_USING_POINTER_EQUALITY
Using pointer equality to compare different types
使用指针比较不同的类型
EQ_ALWAYS_FALSE
equals method always returns false
使用equals方法返回值总是false
EQ_ALWAYS_TRUE
equals method always returns true
equals方法返回值总是true
EQ_COMPARING_CLASS_NAMES
equals method compares class names rather than class objects
equals方法比较类名而不是比较类
EQ_DONT_DEFINE_EQUALS_FOR_ENUM
Covariant equals() method defined for enum
为枚举类型定义了equals()方法
EQ_OTHER_NO_OBJECT
equals() method defined that doesn’t override equals(Object)
定义equals()方法,但是没有覆盖equals(Object)
EQ_OTHER_USE_OBJECT
equals() method defined that doesn’t override Object.equals(Object)
定义equals()方法,但是没有覆盖Object.equals(Object)
EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC
equals method overrides equals in superclass and may not be symmetric
equals方法覆盖了父类的equals可能功能不符
EQ_SELF_USE_OBJECT
Covariant equals() method defined, Object.equals(Object) inherited
类中定义了一组equals方法,但是都是继承的java.lang.Object class中的equals(Object)方法
VA_FORMAT_STRING_BAD_ARGUMENT
Format string placeholder incompatible with passed argument
格式化字符串占位符与传入的参数不匹配
VA_FORMAT_STRING_BAD_CONVERSION
The type of a supplied argument doesn’t match format specifier
指定的格式字符串和参数类型不匹配,例如:String.format(“%d”, “1”)
VA_FORMAT_STRING_EXPECTED_MESSAGE_FORMAT_SUPPLIED
MessageFormat supplied where printf style format expected
需要使用printf样式时却使用了MessageFormat,从而引起格式化结果出错
VA_FORMAT_STRING_EXTRA_ARGUMENTS_PASSED
More arguments are passed than are actually used in the format string
使用字符串格式化时传递了多余的参数
VA_FORMAT_STRING_ILLEGAL
Illegal format string
格式化String对象语句错误
VA_FORMAT_STRING_MISSING_ARGUMENT
Format string references missing argument
String的format操作缺少必要的参数。
VA_FORMAT_STRING_NO_PREVIOUS_ARGUMENT
No previous argument for format string
格式字符串定义错误,例如:formatter.format(“%<s %s”, “a”, “b”); 抛出MissingFormatArgumentException异常
GC_UNRELATED_TYPES
No relationship between generic parameter and method argument
泛型参数与方法参数没有相互关系
HE_SIGNATURE_DECLARES_HASHING_OF_UNHASHABLE_CLASS
Signature declares use of unhashable class in hashed construct
在哈希构造中声明了无法使用哈希算法的类
HE_USE_OF_UNHASHABLE_CLASS
Use of class without a hashCode() method in a hashed data structure
在哈希数据结构中使用的类没有定义hashCode()方法
ICAST_INT_CAST_TO_DOUBLE_PASSED_TO_CEIL
integral value cast to double and then passed to Math.ceil
integral的值转换为double后使用了Math.ceil方法
ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND
int value cast to float and then passed to Math.round
int 类型的值转换为float类型之后调用了Math.round方法
IJU_ASSERT_METHOD_INVOKED_FROM_RUN_METHOD
JUnit assertion in run method will not be noticed by JUnit
在JUnit中的断言在run方法中不会被告知
IJU_BAD_SUITE_METHOD
TestCase declares a bad suite method
在一个JUnit类中声明的一个suite()方法必须声明为 public static junit.framework.Test suite() 或者 public static junit.framework.TestSuite suite() 的形式。
IL_CONTAINER_ADDED_TO_ITSELF
A collection is added to itself
集合本身作为add方法的参数,这样会引起内存溢出。
IL_INFINITE_LOOP
An apparent infinite loop
无法跳出的递归方法引起的死循环
IM_MULTIPLYING_RESULT_OF_IREM
Integer multiply of result of integer remainder
和整数余数进行乘法运算。例如:i % 60 1000 是进行(i % 60) 1000运算而不是 i % (60 * 1000)
INT_BAD_COMPARISON_WITH_NONNEGATIVE_VALUE
Bad comparison of nonnegative value with negative constant
错误地比较非负数与负数
INT_BAD_COMPARISON_WITH_SIGNED_BYTE
Bad comparison of signed byte
比较有符合数,要先把有符号数转换为无符合数再进行比较
IO_APPENDING_TO_OBJECT_OUTPUT_STREAM
Doomed attempt to append to an object output stream
试图在对象的输出流处添加元素,如果你希望能够添加进一个对象的输出流中,那么必须保证对象的输出流处于打开状态。
IP_PARAMETER_IS_DEAD_BUT_OVERWRITTEN
A parameter is dead upon entry to a method but overwritten
传入参数的值没有被使用,但是对传入值进行了修改,并返回给了调用者
MF_CLASS_MASKS_FIELD
Class defines field that masks a superclass field
子类中定义了和父类中同名的字段。在调用时会出错
MF_METHOD_MASKS_FIELD
Method defines a variable that obscures a field
在方法中定义的局部变量和类变量或者父类变量同名,从而引起字段混淆。
NP_ALWAYS_NULL
Null pointer dereference
对象赋为null值后 没有被重新赋值
NP_ALWAYS_NULL_EXCEPTION
Null pointer dereference in method on exception path
方法的异常路径中引用了空指针
NP_ARGUMENT_MIGHT_BE_NULL
Method does not check for null argument
方法没有判断参数是否为空
NP_CLOSING_NULL
close() invoked on a value that is always null
一个为空的对象调用close方法
NP_GUARANTEED_DEREF
Null value is guaranteed to be dereferenced
存在一定会被调用的null对象
NP_NONNULL_PARAM_VIOLATION
Method call passes null to a nonnull parameter
方法中为null的参数没有被重新赋值
NP_NONNULL_RETURN_VIOLATION
Method may return null, but is declared @NonNull
方法声明了返回值不能为空,但是方法中有可能返回null
NP_NULL_INSTANCEOF
A known null value is checked to see if it is an instance of a type
一个已知的null值被用来判断它是否是一个类型的实例
NP_NULL_ON_SOME_PATH
Possible null pointer dereference
可能出现空指针引用
NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS
method call passes null for nonnull parameter
方法参数中声明为nonnull类型的参数为null
NP_STORE_INTO_NONNULL_FIELD
Store of null value into field annotated NonNull
一个已经声明为不能为null值的属性被赋值为null。
NM_BAD_EQUAL
Class defines equal(Object); should it be equals(Object)?
类中定义了一个equal方法但是却不是覆写的Object对象的equals方法
NM_LCASE_HASHCODE
Class defines hashcode(); should it be hashCode()?
类中定义了一个hashCode方法但是却不是覆写的Object中的hashCode方法
NM_LCASE_TOSTRING
Class defines tostring(); should it be toString()?
类中定义了一个toString方法但是却不是覆写的Object中的toString方法
NM_METHOD_CONSTRUCTOR_CONFUSION
Apparent method/constructor confusion
构造方法定义混乱
NM_VERY_CONFUSING
Very confusing method names
混乱的方法命名,如getName和getname方法同时出现的时候
NM_WRONG_PACKAGE
Method doesn’t override method in superclass due to wrong package for parameter
因为包名不正确所以没能正确覆盖父类的方法
QBA_QUESTIONABLE_BOOLEAN_ASSIGNMENT
Method assigns boolean literal in boolean expression
在if或者while表达式中使用boolean类型的值时应该使用==去判断,而不是采用=操作
RC_REF_COMPARISON
Suspicious reference comparison
比较两个对象值是否相等时应该采用equals方法,而不是==方法
RE_BAD_SYNTAX_FOR_REGULAR_EXPRESSION
Invalid syntax for regular expression
对正则表达式使用了错误的语法,会抛出未经检查的异常
RE_CANT_USE_FILE_SEPARATOR_AS_REGULAR_EXPRESSION
File.separator used for regular expression
在正则表达式中使用了错误的文件分隔符,在windows系统中正则表达式不会匹配’\’而应该使用’\‘
RV_01_TO_INT
Random value from 0 to 1 is coerced to the integer 0
从0到1随机值被强制为整数值0。在强制得到一个整数之前,你可能想得到多个随机值。可以使用Random.nextInt(n)的方法。
RV_ABSOLUTE_VALUE_OF_HASHCODE
Bad attempt to compute absolute value of signed 32-bit hashcode
此代码生成一个哈希码,然后计算该哈希码的绝对值。如果哈希码是Integer.MINVALUE的,那么结果将是负数(因为Math.abs(Integer.MIN_VALUE的)== Integer.MIN_VALUE的)。
在2^ 32值之外字符串有一个Integer.MIN_VALUE的hashCode包括“polygenelubricants”,“GydZG”和“,”DESIGNING WORKHOUSES “。
RV_ABSOLUTE_VALUE_OF_RANDOM_INT
Bad attempt to compute absolute value of signed 32-bit random integer
此代码生成一个随机的符号整数,然后计算该随机整数的绝对值。如果随机数生成数绝对值为Integer.MIN_VALUE的,那么结果将是负数(因为Math.abs(Integer.MIN_VALUE的)== Integer.MIN_VALUE的)。
RV_EXCEPTION_NOT_THROWN
Exception created and dropped rather than thrown
此代码创建一个异常(或错误)的对象,但不会用它做任何事情。
RV_RETURN_VALUE_IGNORED
Method ignores return value
方法忽略了返回值,应该对返回值进行检查
RpC_REPEATED_CONDITIONAL_TEST
Repeated conditional tests
该代码包含对同一个条件试验了两次,两边完全一样例如:(如X == 0 | | x == 0)。可能第二次出现是打算判断别的不同条件(如X == 0 | | y== 0)。
SA_FIELD_DOUBLE_ASSIGNMENT
Double assignment of field
对属性进行双重赋值
SA_FIELD_SELF_ASSIGNMENT
Self assignment of field
属性自身赋值
SA_FIELD_SELF_COMPARISON
Self comparison of field with itself
属性自己与自己进行了比较
SA_LOCAL_SELF_COMPARISON
Self comparison of value with itself
自己和自己的值比较
SA_LOCAL_SELF_COMPUTATION
Nonsensical self computation involving a variable (e.g., x & x)
此方法对同一变量执行了无意义的计算(如x&x或x-x)操作。由于计算的性质,这一行动似乎没有意义,并可能表明错误或逻辑错误。
SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH
Dead store due to switch statement fall through
在swtich中先前的case值因为swtich执行失败而被覆写,这就像是忘记使用break推出或者没有使用return语句放回先前的值一样。
SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH_TO_THROW
Dead store due to switch statement fall through to throw
在swtich中因为出现异常而忽略了对case值的保存。
SIC_THREADLOCAL_DEADLY_EMBRACE
Deadly embrace of non-static inner class and thread local
如果线程包含对一个内部类实例的引用,那么内外实例的实例都可以被获取,这样就不具备垃圾会回收的资格。
SIO_SUPERFLUOUS_INSTANCEOF
Unnecessary type check done using instanceof operator
在进行instanceof操作时进行没有必要的类型检查
STI_INTERRUPTED_ON_CURRENTTHREAD
Unneeded use of currentThread() call, to call interrupted()
此方法调用Thread.currentThread(),只需调用interrupted()方法。由于interrupted()是一个静态方法, Thread.interrupted()更简单易用。
STI_INTERRUPTED_ON_UNKNOWNTHREAD
Thread.interrupted() method invoked on thread instance
调用不是当前线程对象的Thread.interrupted()方法,由于interrupted()方法是静态的,interrupted方法将会调用一个和作者原计划不同的对象。
SE_METHOD_MUST_BE_PRIVATE
Method must be private in order for serialization to work
这个类实现了Serializable接口,并定义自定义序列化的方法/反序列化。但这种方法不能声明为private,否则将被序列化/反序列化的API忽略掉。
SE_READ_RESOLVE_IS_STATIC
The readResolve method must not be declared as a static method.
为使readResolve方法得到序列化机制的识别,不能作为一个静态方法来声明。
UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS
Uncallable method defined in anonymous class
在匿名类中定义了一个既没有覆写超类中方法也不能直接调用的方法,因为在其他类的方法不能直接引用匿名类声明的方法,似乎这种方法不能被调用,这种方法可能只是没有任何作用的代码,但也可能是覆写超类中声明。
UR_UNINIT_READ
Uninitialized read of field in constructor
此构造方法中使用了一个尚未赋值的字段或属性。
UR_UNINIT_READ_CALLED_FROM_SUPER_CONSTRUCTOR
Uninitialized read of field method called from constructor of superclass
父类的构造方法调用未初始化属性的方法
其他文章(持续更新)
FindBugs:简介与使用
FindBugs 规则整理:Bad Practice
FindBugs 规则整理:Style & Dodgy
FindBugs 规则整理:Malicious Code Vulnerability
FindBugs 规则整理:Multithreaded Correctness
FindBugs 规则整理:Security & Experimental
FindBugs 规则整理:Performance
FindBugs 规则整理:Internationalization
引用
整合以下文章过程中发现部分存在翻译错误,已做修正,同时感谢以下文章作者
FindBugs使用备忘录
FindBugs规则整理
详解FindBugs的各项检测器
Findbugs 缺陷详解与英文代号的对照表