前言
这两天组长要求对项目的代码进行一遍检查。于是我就使用了IDE的finfBugs插件检查了一遍代码,在这里记录下findbugs中常见的bug描述。FindBugs问题汇总
检查工具:FindBugsBug级别
- Scariest(最高bug级别)
- Scary
- Troubling
- Of Concern
Scariest描述
- Useless self-operation(描述:自我赋值,将值自己赋值给了自己,不知道为什么会有这种奇怪的东西)。 比如:在某个类中的set方法 set(String s) {this.s = this.s}属于此类问题。
- Synchronization on field in futile attempt to guard that field(描述:同步字段可能无效)。
- Method ignores return values (描述:忽略了方法的返回值)。 比如:String类型的字段在调用replace方法后没有重新赋值。
- Comparing incompatible types for equality:call equals() to comparing different types(描述:equals方法比较了不同的类型)。 比如:"".equals(productNameList),其中productNameList是数组类型。
- Suspicious reference comparison(描述:可疑的引用类型比较,该类型不适用于==比较)。 比如:Duble.valueOf(v) == Double.valueOf("0"),Double.ValueOf方法返回的类型是有个Double引用,不建议两个引用之间直接使用==。
- No relationship between generic parameter and method argument(描述:使用Collection类中的contains\get\remove方法比较时,两个参数类型不致)。
- Bad comparison if int value long constant(描述:int类型的值与long类型的值进行了比较)。
- Very confusing method names(描述:十分困惑的方法名,方法名的首字母不应该用 大写)。
Scary级别
- Null pointer dereference(空指针间接引用)。
- Null value is guaranteed to be dereferenced(描述:保证取消引用null)。某个字段可能为null。 Possible null pointer dereference(可能为null引用)。在某些类中的对象可能为null。
- Method call passes null for non-null parameter(描述:方法调用对非null参数调用null)。f = Float.parseFloat(value)中value可能为null。
- A known null value is checked to see if it is an instance of a type(描述:检查已知的null值以查看它是否是类型的实例)。比如:if(info == null&&info instance SomeClass)。
- Null pointer dereference(描述:空指针间接引用)。比如:if(v == null && ..)在之后的逻辑中为null的v字段可能被引用。
- Non-virtual method call passes null for non-null parameter(描述:对要求非null参数的方法传递了null参数)。比如:某个方法中传递了null参数。
- Read of unwritten field(描述:不能写入的字段读取)。比如:在某个方法中Button未经初始化就是设置属性。
- Synchronization performed on java.util.CopyOnWriteArrayList(描述:对CopyOnWriteArrayList上了锁)。比如:对线程安全容器又加了一次锁由于CopyOnWriteArrayList已支持同步,不需要加锁。
- Incorrect lazy initialization and update of static field(描述:静态字段不正确的懒加载和更新)。比如:建议在返回单例实例的时候建议加同步锁。
- Repeated conditional test(描述:重复的判断条件)。比如:if(index - 1|| index - 1)判断条件重复。
- Doomed test for equality to NaN(描述:与NaN进行比较)。比如:if(d == 0 || d == Double.NaN)由于NaN的特殊语义,没有值等于NaN,包括NaN本身,所以d == Double.NaN 总是为false。
- Int value cast to float then passed to Math.round(描述:int类型的值先转型为float然后再传入Math.round方法)。
- Call to static DateFormat(描述:调用了静态的DateFormat)。由于DateFormate不是线程安全的,推荐使用内部属性的方式调用。
- Bad Comparison of nonnegative value with negative constant or zero(描述:非负数和0或者负数的比较)。比如:if(list != null && list.size()>0)其中list.size()返回值大于等于0 永真。
- Infinite loop(描述:无限循环)。比如:某个方法产生了递归无限循环调用。
- Invocation of toString on an array(描述:数组类型调用了toString方法)。建议使用Array.toString方法。
- A Parameter is dead upon entry to a method but overwritten.(描述:参数在进入方法时就被杀死了,这里的情况是参数被计算赋值没有被使用)。
- Covariant equals() method defined,Object.equals() inherited.(描述:应该重写object.equals()方法)。比如:重写了equals()方法,但参数不是Object类型,这里的建议是重写Object.equals()方法。
- Format String problem.(描述:String格式化问题)。比如:String.format方法需要6个参数,但只传了5个。
- Useless assignment in return(描述:在return语句中进行了没用的赋值)。比如:return a= b.getBoolean(),a不需要再赋值。
- Class defines field that mask a superclass field.(子类声明的参数覆盖了父类相同名称的参数)。
Troubling级别
- Class defines equals() and uses Object.hashCode().(描述:类重写了equals()的同时也需要使用hashCode()方法)。
- NullCheck of value previously dereferenced.(描述:在进行null检查时已经使用,不需要在这里进行判空)。
- Non-transient non-serializable instance field in serializable class.(描述:在可序列化的类中成员变量的引用没有实现序列化接口,可能造成NotSerializableException异常)。
- Null Pointer dereferenced.(null值可能被引用)。
- Class names should not shadow simple name of superclass.(描述:某个类的名字和父类名称一样)。
- Class defines clone() but does not implement cloneable.(描述:某个类重写了clone()方法却没有实现Cloneable接口)。
- Condition has no effect(描述:判断条件没有作用)。比如:在某个方法中,i已经经过计算,if(i == -1)这个条件永假。
- Possible double check of field.(描述:某个属性存在双重检查)。比如:在某个中,getInstance对instance进行了两次判空。
- Unsynchronized get method,Synchronized set method(描述:get方法不是同步的,但set方法是同步的)。
- Comparison of String parameter using == or !=(描述:对String类型的数据使用==或者!=进行了比较)。
- Dead store to local variable that shadows field.(描述:计算之后的值赋值到局部变量)。比如:局部变量被赋值后没有被使用。
- static use of type Calendar or DateFormat(描述:使用了静态的Calendar或者DateFormat)。因为Calendar和DateFormat不是线程安全的,使用静态数据可能造成数据不一致。
- Check for oddness that will not work for negative numbers.(描述:检查奇数的方法使用x % 2 == 1在x为负数是无效)。这里建议使用x & 1 == 1或者 x % 2 != 0来判断。
- An increment to a volatile field is not atomic.(描述:volatile修饰的字段++操作不具有原子性)。
- Unwritten field.(描述:没有被写入的字段)。这里是有些字段没有被赋值或者初始化,当读取字段时还是原来的值。
Of Concern级别
- Confusing method name.(描述:令人迷惑的方法名)
- Method names should start with a lower case letter.(描述:方法名应该以小写开头)。
- Class names should start with a upper case letter.(描述:类名应该以大写开头)。
- Field names should start with a lowercase letter.(描述:属性名应该以小写开头)。
- Dead store to local variable that shadows field.(描述:计算之后的值赋值到局部变量,但局部变量没有被使用)。
- Switch case falls through.(描述:switch的用例判定)
- Switch statement found where one case falls through to the next case.(描述:switch语句也在下一条运行)。这里是在case语句中没有使用break关键字,所以也会运行下一条语句。
- Switch statement found where default case is missing.(描述:switch没有default语句)。
- May expose internal representation by incorporating reference to mutable object.(描述:可以通过合并对可变对象的引用来公开内部表示)。这里是指的是setter方法使用引用传递,外部对象的修改也可能造成内部对象的修改。
- Exception is caught when Exception is not thrown.(描述:方法使用捕获异常对象的try-catch块,但不会在try块中抛出异常)。这里指的是建议使用特定异常。
- Unsatisfied obligation to clean up stream or resource.(描述:不能保证资源和流被正确释放)。这里指的是有些文件流资源可能不能被释放。
- Bad use of return value from method.(描述:没有使用方法的返回值)。这里指的是方法的返回值没有被使用,只执行了方法。
- Redundant comparison to null.(描述:与null的冗余比较)。这里是对一些字段进行了重复的null检查。
- Serializable class with no Version ID.(描述:序列化类没有定义序列化id)。某个类没有定义序列化id。
- Questionable Boxing of primitive value.(描述:自动拆箱问题)。这里指的是在程序中存在int i = Integer.valueOf(str) 。其中Integer.valueOf()返回Integer对象。
- Dubious method used.(描述:可疑的方法调用)。这里指的是一些方法不适当的使用。
- Method uses the same code for two branch.(描述:方法中两个判断分支有相同的操作)。这里只的是if{}else{}中的逻辑相同。
- Integral division result cast to double or float.(描述:处罚结果变为double或float)。这里指的是int进行除法时的转型。比如:int x = 2; int y = 5; // 错误的方式:double value1 = x / y = 0.0;
// 正确的方式:
double value2 = x / (double) y = 0.4- Null pointer dereference(空指针间接引用)。
- Useless code.(描述:没用处的代码)。这里主要是指空逻辑 比如:if{}。
- Bad cast of Object reference.(描述:不良的转型)。这里有相同类型的对象使用instance关键字进行了判断,或者没有被instanceof判断。
- Method concatenates strings using + in a loop.(描述:在循环中使用+操作符对string进行拼接)。
- Mutable static field.(描述:可变的静态字段)。这里指的是不推荐static字段是可变的。
- Load of known null value.(描述:使用了已知的null值)。比如:在NewsGundongPinnedSectionListView类中initSectionAndTimeData方法中,if(c == null && ''.equals(c))。
- Useless control flow.(描述:没有用处的控制语句)。这里指的是if空逻辑或者for空逻辑。
- Format string should use %n rather than \n.(描述:String格式化语句中应该用%n代替\n)。
- Method ignores results of InputStream.read().(描述:方法中忽略了read()方法的返回结果)。这里指的是read()方法返回的结果在方法中没有被使用。
- Test for floating point equality.(描述:使用了==或!=来判断float或double)。这里指的是float或double计算结构有精度,相同的计算不一定得到相同的结果,应用在判断是加上一定的精度范围,比如:Math.abs(x - y) > 0.0000001。
- Enum field is public or mutable.(描述:枚举字段是public和可变的)。这里建议使用final的。
- Private method is never used.(描述:私有方法没有被调用)。
- Write to static field from instance method.(描述:从实例方法写入静态字段)。这里是说在多个实例操作时可能不造成其他结果。
- Double assignment of field.(描述:同一个字段两次赋值)。指的是在初始化是对同一个字段进行了两次相同的初始化。
- Vacuous bit mask operation on integer value.(描述:整数值上的空位掩码操作)。
- Method may fail to close stream.(描述:流资源可能关闭失败)。这里有些流资源没有主动关闭。
- Inefficient use of ketSet iterator instead of entrySet iterator.(描述:低效使用keySet迭代器而不是entrySet迭代器)。这里建议使用entrySet迭代器。共61条。
- Class implements Cloneable but does not define or use clone method.(描述:类实现了Cloneable接口没有实现clone方法)。
- Method might ignore exception.(描述:方法可能忽略异常)。这里指的是异常没有进行处理。
- Potentially dangerous use of non-short-circuit logic.(描述:存在非短路逻辑风险)。这里指的是返回的boolean类型使用&操作符进行处理。
- Unwritten field.(描述:没有被写入的字段)。这里是有些字段没有被赋值或者初始化,当读取字段时还是原来的值。
- Unread field.(描述:没有被读取的字段)。这里是指没有被使用过的字段,建议删除。
- Should be static inner class.(描述:应该使用静态内部类)。这里指的是建议使用静态内部类。
- Unused field.(描述:没有被使用的字段)。这里是指定义的字段没有被调用,建议删除。
- Unread field:should this field be static?(描述:有些私有final类型的字段是否需要设置为静态的)。
- Inconsistent synchronization.(描述:不一致的同步)。这里是因为设置变量时进行同步而在读取时没有进行同步。
总结
以上就是在本次扫描代码后遇到的大多数问题。FindBugs中的问题描述还是比较精准的,而且其中也有很多有用的建议,值得采用并利用到代码中。