findbugs插件查出bug总结

1.用对象之前需要先判断对象是否为空

2.用equal判断值是否相等时,需要两者的数据类型是相同的,否则永远为假。如:将StringBuffer对象的值与空字符串【""】比较时为假(空字符串为String类型,两者类型不一样),且任何情况下,x.equals(null),永远返回是“false”;即x.equals(和x不同类型的对象)永远返回是“false”

3.ignores exceptional return value of java.io.File.mkdirs()

 忽略了返回值,应当含有返回值

后来我在调用.mkdirs()的地方加了try catch异常处理,即如果创建目录失败就抛出异常。【不知道是否是最佳方案,期待高手指点!】

 

4.Object   aObject   =   new   Object();   aObject   =   aPhoneBook.put("abc",   "123456");

用findbug檢查會出現Dead store to local variable的錯誤,他的意思是“本地变量存储了闲置不用的对象”

為什么會出現這個原因呢? 因為           Object   aObject   =   new   Object();  
  这一句执行3个动作:  
  1)创建一个引用  
  2)创建一个Object对象  
  3)把Ojbect的引用赋值给aObject  
   
  其中,后面两个动作是多余的,因为后面的程序中你没有使用这个新建的Object,而是重新给aObject赋值。

所以,只需要  
          Object   aObject;  
  就可以了  

 

5.FindBugs推荐使用Integer.ValueOf(int)代替new Integer(int),因为这样可以提高性能。如果当你的int值介于-128~127时,Integer.ValueOf(int)的效率比Integer(int)快大约3.5倍。

下面看看JDK的源码,看看到Integer.ValueOf(int)里面做了什么优化:

public   static  Integer valueOf( int  i) {
  
final   int  offset  =   128 ;
  
if  (i  >=   - 128   &&  i  <=   127 ) {  //  must cache
     return  IntegerCache.cache[i  +  offset];
  }
  
return   new  Integer(i);




private   static   class  IntegerCache {
  
private  IntegerCache(){}
    
  
static   final  Integer cache[]  =   new  Integer[ - ( - 128 +   127   +   1 ];
  
static  {
  
for ( int  i  =   0 ; i  <  cache.length; i ++ )
     cache 
=   new  Integer(i  -   128 );
  }
}

从源代码可以知道,ValueOf对-128~127这256个值做了缓存(IntegerCache),如果int值的范围是:-128~127,在ValueOf(int)时,他会直接返回IntegerCache的缓存给你。

所以你会看到这样的一个现象:

public   static   void  main(String []args) {
     Integer a 
=   100 ;
     Integer b 
=   100 ;
     System.out.println(a
== b);

     Integer c 
=   new  Integer( 100 );
     Integer d 
=   new  Integer( 100 );
     System.out.println(c
== d);
}

结果是:

true
false

因为:java在编译的时候 Integer a = 100; 被翻译成-> Integer a = Integer.valueOf(100);,所以a和b得到都是一个Cache对象,并且是同一个!而c和d是新创建的两个不同的对象,所以c自然不等于d。

 

再看看这段代码:

public   static   void  main(String args[])  throws  Exception{
        Integer a 
=   100 ;
        Integer b 
=  a;
        a 
=  a  +   1 ;  //或者a++;
        System.out.println(a
== b);
}
结果是:false

因为在对a操作时(a=a+1或者a++),a重新创建了一个对象,而b对应的还是缓存里的100,所以输出的结果为false。


6.makes inefficient use of keySet iterator instead of entrySet iterator【意思是说用keySet 方式遍历Map的性能不如entrySet性能好】
 
Set<Map.Entry<K,V>> entrySet()
          返回此映射中包含的映射关系的 Set 视图。

 

 Set<K> keySet()
          返回此映射中包含的键的 Set 视图。



第一种方式


第二种方式

性能比较测试类:
 


通过测试发现,第二种方式的性能通常要比第一种方式高一倍.

原因分析:

  通过查看源代码发现,调用这个方法keySetMap.keySet()会生成KeyIterator迭代器,其next方法只返回其key值.

 
Java代码

而调用entrySetMap.entrySet()方法会生成EntryIterator 迭代器,其next方法返回一个Entry对象的一个实例,其中包含key和value.

 
Java代码
二者在此时的性能应该是相同的,但方式一再取得key所对应的value时,此时还要访问Map的这个方法,这时,方式一多遍历了一次table.

Java代码
这个方法就是二者性能差别的主要原因.




你可能感兴趣的:(java,object,String,Integer,iterator,Class)