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)里面做了什么优化:
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的缓存给你。
所以你会看到这样的一个现象:
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。
再看看这段代码:
Integer a = 100 ;
Integer b = a;
a = a + 1 ; //或者a++;
System.out.println(a == b);
}
因为在对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 视图。
|
第一种方式
Iterator<String> keySetIterator = keySetMap.keySet().iterator();
while (keySetIterator.hasNext()) {
String key = keySetIterator.next();
String value = keySetMap.get(key);
}
第二种方式
Iterator<Entry<String, String>> entryKeyIterator = entrySetMap.entrySet()
.iterator();
while (entryKeyIterator.hasNext()) {
Entry<String, String> e = entryKeyIterator.next();
String value=e.getValue();
}
性能比较测试类:
public class HashMapTest {
public static void main(String[] args) {
HashMap<String, String> keySetMap = new HashMap<String, String>();
HashMap<String, String> entrySetMap = new HashMap<String, String>();
for (int i = 0; i < 1000; i++) {
keySetMap.put("" + i, "keySet");
}
for (int i = 0; i < 1000; i++) {
entrySetMap.put("" + i, "entrySet");
}
long startTimeOne = System.currentTimeMillis();
Iterator<String> keySetIterator = keySetMap.keySet().iterator();
while (keySetIterator.hasNext()) {
String key = keySetIterator.next();
String value = keySetMap.get(key);
System.out.println(value);
}
System.out.println("keyset spent times:"
+ (System.currentTimeMillis() - startTimeOne));
long startTimeTwo = System.currentTimeMillis();
Iterator<Entry<String, String>> entryKeyIterator = entrySetMap
.entrySet().iterator();
while (entryKeyIterator.hasNext()) {
Entry<String, String> e = entryKeyIterator.next();
System.out.println(e.getValue());
}
System.out.println("entrySet spent times:"
+ (System.currentTimeMillis() - startTimeTwo));
}
}
通过测试发现,第二种方式的性能通常要比第一种方式高一倍.
原因分析:
通过查看源代码发现,调用这个方法keySetMap.keySet()会生成KeyIterator迭代器,其next方法只返回其key值.
private class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}
而调用entrySetMap.entrySet()方法会生成EntryIterator 迭代器,其next方法返回一个Entry对象的一个实例,其中包含key和value.
private class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}
二者在此时的性能应该是相同的,但方式一再取得key所对应的value时,此时还要访问Map的这个方法,这时,方式一多遍历了一次table.
public V get(Object key) {
Object k = maskNull(key);
int hash = hash(k);
int i = indexFor(hash, table.length);
Entry<K,V> e = table[i];
while (true) {
if (e == null)
return null;
if (e.hash == hash && eq(k, e.key))
return e.value;
e = e.next;
}
}
这个方法就是二者性能差别的主要原因.
findbugs插件查出bug总结相关推荐
- findbugs插件_Intellij静态代码扫描插件SpotBugs
最近要做Java静态扫描的部分工作,之前是在Jenkins上使用findbugs插件完成的,但是由于现在Jenkins权限收回和Java代码权限的放开(我也搞不懂这两者的关联性),目前打算在本地完成静 ...
- findbugs html报告,利用findBugs插件来扫描代码,并用ant生成报告
最近项目要用findbugs插件来生成报告,总结了一下用法和如何生成报告 1, 把下载的压缩包解压后,把 copy到eclipse的plugin目录中去: 2, 重新启动eclipse 3, 打开ec ...
- 在Eclipse或MyEclipse中安装findbugs插件
2019独角兽企业重金招聘Python工程师标准>>> 我们都知道,在Eclipse或MyEclipse中安装插件有两种方式,一种是在线安装,第二种是先下载插件然后在本地安装. 在这 ...
- android studio字符串转整型,Android Studio 中的FindBugs插件使用,轻松帮你发现Bug (转)...
在日常开发过程中难免会因为一时疏忽而留下一些Bug,这些Bug就是埋在程序里的定时炸弹,如果不能及时铲除就会导致程序的不稳定,异常或闪退的现象,从而导致用户的体验的下降.那么怎么才能找出这些埋在程序里 ...
- Android Studio 中的FindBugs插件使用,轻松帮你发现Bug (转)
在日常开发过程中难免会因为一时疏忽而留下一些Bug,这些Bug就是埋在程序里的定时炸弹,如果不能及时铲除就会导致程序的不稳定,异常或闪退的现象,从而导致用户的体验的下降.那么怎么才能找出这些埋在程序里 ...
- findbugs插件_提升编码效率的IntelliJ IDEA必备插件
点击蓝色"程序职场"关注我哟 加个"星标",天天和你一起进步 作者 | 房上的猫 来源 | cnblogs.com/lsy131479/p/9646444.ht ...
- FindBugs插件
在日常开发过程中难免会因为一时疏忽而留下一些Bug,这些Bug就是埋在程序里的定时炸弹,如果不能及时铲除就会导致程序的不稳定,异常或闪退的现象,从而导致用户的体验的下降.那么怎么才能找出这些埋在程序里 ...
- Eclipse FindBugs插件安装与使用
前言: 白盒测试中的静态检查一般是检查编码标准规范,错误列表.编码规范往往团队会根据自己的经验和风格进行设置一些规范.现在很多IDE工具都会在编辑代码的时候实时的提醒是否符合代码风格.错误列表,一般是 ...
- php findbugs,findBugs插件
现在使用Java进行开发的软件已经很多了,那么我们在使用Java开发的时候,是不是会遇到各种各样的错误了,有的错误隐藏着,有的错误你发现了,可以修改,那没有发现的错误就令人担忧了!小编这款插件就可以帮 ...
最新文章
- Recommenders with TensorRT
- 前端处理带t的时间_大厂实践:如何优雅的监控前端页面性能
- 【BZOJ5102】[POI2018]Prawnicy 堆
- 任正非最新内部信:过去只为赚点小钱,现在要用5G+AI战胜美国
- ESP8266/ESP32自动下载电路分析
- 史上最详细的MySQL操作事例
- hive中的UDAF的使用流程记载
- Linux存储保护,谈谈Linux中的存储保护
- 面型对象 (接口与类的区别)
- Python 小白从零开始 PyQt5 项目实战(5)布局管理
- Comet服务器推送与SignalR
- 禁止拖放对象文本被选择的方法
- 人脸识别mtcnn原理
- opencv改变图片大小,cv2.resize方法详解
- 1059604-93-1,m-PEG13-Ms甲磺酸基是亲核取代反应的良好离开基
- 服务器做网站空间,用服务器做网站空间
- 1048 数字加密 (20分)
- 【哈夫曼树】JZOJ_4210 我才不是萝莉控呢
- 服务器护卫神怎么上传文件,护卫神备份文件的方法
- FCKeditor使用详解(汇总)