FindBugs Warnings 警告类型文档
一、
Type : EI_EXPOSE_REP
Category:MALICIOUS_CODE(恶意程序代码)
描述:may exposeinternal representation by returning getter方法返回引用类型
eclipse自动生成的引用类型(Object、数组、Date等)的getter、setter方法会得到或通过对可变对象的引用操作而暴露代码内部实现,解决方法很多,只要返回的或赋值的对象不是原引用对象即可。
例如:
以Date类型为例:
private java.util.Datefirstdate;
publicvoidsetFirstdate(java.util.Datevalue) {
this.firstdate =value;
}
public java.util.Date getFirstdate(){
returnthis.firstdate;
}
改为:
public String getFirstdate() {
returnfirstdate;
}
publicvoidsetFirstdate(Stringfirstdate) {
this.firstdate =firstdate;
}
二、
Type : EI_EXPOSE_REP2
Category:MALICIOUS_CODE(恶意程序代码)
描述:may expose internal representation by storing an externallymutable object into setter方法返回引用类型
eclipse自动生成的引用类型(Object、数组、Date等)的getter、setter方法会得到或通过对可变对象的引用操作而暴露代码内部实现,解决方法很多,只要返回的或赋值的对象不是原引用对象即可。
例如:
以Date类型为例:
private java.util.Datefirstdate;
publicvoidsetFirstdate(java.util.Datevalue) {
this.firstdate =value;
}
public java.util.DategetFirstdate() {
returnthis.firstdate;
}
改为:
public String getFirstdate() {
returnfirstdate;
}
publicvoid setFirstdate(Stringfirstdate) {
this.firstdate =firstdate;
}
三、
Type : WMI_WRONG_MAP_ITERATOR
Category:PERFORMANCE(性能)
描述:使用keySet迭代器无效,请使用entrySet迭代器代替
解释:很多人都这样遍历Map,没错,但是效率很低,先一个一个的把key遍历,然后在根据key去查找value,这不是多此一举么,为什么不遍历entry(桶)然后直接从entry得到value呢?它们的执行效率大概为1.5:1(有人实际测试过)。
我们看看HashMap.get方法的源代码:
publicV get(Object key) {
if (key==null)
returngetForNullKey();
inthash=hash(key.hashCode());
for (Entry<K,V> e =table[indexFor(hash,table.length)];e !=null;e = e.next) {
Object k;
if (e.hash ==hash&& ((k =e.key) == key || key.equals(k)))
returne.value;
}
returnnull;
}
从这里可以看出查找value的原理,先计算出hashcode,然后散列表里取出entry,不管是计算hashcode,还是执行循环for以及执行equals方法,都是CPU密集运算,非常耗费CPU资源,如果对一个比较大的map进行遍历,会出现CPU迅速飚高的现象,直接影响机器的响应速度,在并发的情况下,简直就是一场灾难。
四、
Type : SE_BAD_FIELD_STORE
Category:BAD_PRACTICE
描述:不可序列化的值存储在一个可序列化类的实例字段中
五、
Type : SBSC_USE_STRINGBUFFER_CONCATENATION
Category:PERFORMANCE(性能)
描述:方法在一个循环中使用“+”运算符拼接字符串
解释:每次循环里的字符串+连接,都会新产生一个string对象,在java中,新建一个对象的代价是很昂贵的,特别是在循环语句中,效率较低。
例如:
六、
Type : RV_RETURN_VALUE_IGNORED_BAD_PRACTICE
Category:BAD_PRACTICE
描述:方法忽略异常的返回值
解释:
关于一个方法逻辑执行是否成功,有两种方式:
一种是抛出异常,一种是提供boolean类型的返回值。举一个例子,用户登录,某些人将login方法的返回值定义为int,然后枚举出各个值的含义,比如0代表成功,1代表用户名不存在等等;而有些人,把这些枚举值看成是use case中的异常流,将它们定义为异常对象,遇到“异常”情况直接抛出异常从而实现分支的流程。第一种方式是典型的C语言面向过程风格,
第二种方式,带有强烈的面向对象味道,特别是java提供了checked Exception,貌似偏离主题了。
java中很多方法的执行成功依赖于异常的分支实现,但也有提供返回值的实现,比如这里的File.delete方法,上面的写法忽略了返回值(如果调用某个方法却不使用其返回值要特别注意),删除一个文件很可能不成功,但是从代码里并没有看到这一层面的意思。
解决方法:
文件删除不成功该怎么办?现在能处理就处理,现在不能处理就把父类的方法也改成有返回值的,然后向上传递,这跟处理异常的道理是一样的,当然,你也可以把它封装成一个异常对象。
例如:
七、
Type : OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE
Category:EXPERIMENTAL
描述:在处理异常时,方法可能未能成功清理流或资源
八、
Type : NP_NULL_ON_SOME_PATH_EXCEPTION
Category:CORRECTNESS
描述:方法中的异常路径上的可能的空指针解引用
例如:
九、
Type : NP_LOAD_OF_KNOWN_NULL_VALUE
Category:STYLE
描述:加载已知为空的值
十、
Type : NM_METHOD_NAMING_CONVENTION
Category:BAD_PRACTICE
描述:方法名应当以小写字母开头
十一、
Type : NM_CLASS_NAMING_CONVENTION
Category:BAD_PRACTICE
描述:类名应当以大写字母开头
十二、
Type : EQ_DOESNT_OVERRIDE_EQUALS
Category:STYLE
描述:类没有覆盖父类中的equals方法
十三、
Type : EQ_COMPARETO_USE_OBJECT_EQUALS
Category:BAD_PRACTICE
描述:类定义了compareTo(...)方法,使用了Object.equals()方法
解释:
没有使用instanceof判断就直接转型,有抛出classcastexception异常的可能。
这个BUG主题是,遵守约定(x.compareTo(y)==0) == (x.equals(y)),强烈建议,但不严格要求。
在return 0的时候,调用equals方法返回true,因为在PriorityQueue.remove方法中,1.5使用的是compareTo方法,而1.6使用的是equals方法,保证环境升级的时候,受影响最小。
解决方法:
在return 0的时候,调用equals方法返回true
例如:
十四、
Type : DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION
Category:BAD_PRACTICE
描述:不要使用removeAll方法清空一个集合
十五、
Type : DM_NUMBER_CTOR
Category:PERFORMANCE(性能)
描述:方法调用无效的Number构造器,请使用valueOf静态方法代替
十六、
Type : DM_NEXTINT_VIA_NEXTDOUBLE
Category:PERFORMANCE(性能)
描述:为了生成一个随机整数,调用Random对象的nextInt方法,而不是nextDouble方法
十七、
Type : DM_BOXED_PRIMITIVE_FOR_PARSING
Category:PERFORMANCE(性能)
描述:使用封装/反封装来解析一个基本类型
例如1:
renturnRecord.setParts(Integer.valueOf(parts[i]));
处理:
renturnRecord.setParts(Integer.valueOf(parts[i]).intValue());
十八、
Type : DLS_DEAD_LOCAL_STORE
Category:STYLE
描述:死存储局部向量
解释:
对本地变量定义了之后未使用到,编译器能够做优化处理,也就是在编译之后的class文件中删除这些本地变量。方法是在eclipse的Preferences里将以下的钩去除:
解决方法:
大胆的去掉或者注释掉。
误报的案例:
是一个局部的变量,不需要定义到外部去,定义在外部,可能会变成一个无效的变量。
例如:
十九、
Type : BX_UNBOXING_IMMEDIATELY_REBOXED
Category:PERFORMANCE(性能)
描述:反封装已经封装的值,然后又立即重新封装
例如:
二十、
Type : UUF_UNUSED_FIELD
Category:PERFORMANCE(性能)
描述:未使用字段
解释:这个警告应该影响不大吧!
例如:
Type :
Category:
描述:
例如: