FindBugs1.3.9规则整理
Posted YongHui_Luo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FindBugs1.3.9规则整理相关的知识,希望对你有一定的参考价值。
Performance关于代码性能相关方面的序号
Description
备注
1.
Bx: Primitive value is boxed and then immediately unboxed (BX_BOXING_IMMEDIATELY_UNBOXED)
对原始值进行装箱,然后立即取消装箱。这可能是在一个未要求装箱的地方进行了手动装箱,从而迫使编译器进行立即撤消装箱的操作
2.
Bx: Primitive value is boxed then unboxed to perform primitive coercion (BX_BOXING_IMMEDIATELY_UNBOXED_TO_PERFORM_COERCION)
对原始值进行装箱然后立即把它强制转换为另外一种原始类型。例如:
new Double(d).intValue()应该直接进行强制转换例如:(int) d
3.
Bx: Method allocates a boxed primitive just to call toString (DM_BOXED_PRIMITIVE_TOSTRING)
仅仅为了调用封装类的toString()而对原始类型进行封装操作。比这种方法更有效的是调用封装类的toString(…)方法例如:
new Integer(1).toString() 替换为 Integer.toString(1)
new Long(1).toString() 替换为 Long.toString(1)
new Float(1.0).toString() 替换为 Float.toString(1.0)
new Double(1.0).toString() 替换为 Double.toString(1.0)
new Byte(1).toString() 替换为 Byte.toString(1)
new Short(1).toString() 替换为 Short.toString(1)
new Boolean(true).toString() 替换为 Boolean.toString(true)
4.
Bx: Method invokes inefficient floating-point Number constructor; use static valueOf instead (DM_FP_NUMBER_CTOR)
使用new Double(double)方法总是会创建一个新的对象,然而使用Double.valueOf(double)方法可以把值保存在编辑器或者class library、JVM中。使用存储值的方式来避免对象的分配可以或得更好的代码性能
除非类必须符合Java 1.5以前的JVM,否则请使用自动装箱或valueOf()方法创建Double和Float实例。
5.
Bx: Method invokes inefficient Number constructor; use static valueOf instead (DM_NUMBER_CTOR)
使用new Integer(int)方法总是会创建一个新的对象,然而使用Integer.valueOf(int)方法可以把值保存在编辑器或者class library、JVM中。使用存储值的方式来避免对象的分配可以或得更好的代码性能
除非类必须符合Java 1.5以前的JVM,否则请使用自动装箱或valueOf()方法创建Long, Integer, Short, Character, Byte实例。
6.
Dm: The equals and hashCode methods of URL are blocking (DMI_BLOCKING_METHODS_ON_URL)
使用equals和hashCode方法来对url进行资源标识符解析时会引起堵塞。考虑使用java.net.URI来代替。
7.
Dm: Maps and sets of URLs can be performance hogs (DMI_COLLECTION_OF_URLS)
方法或者字段使用url的map/set集合。因为equals方法或者hashCode方法来进行资源标识符解析时都会引起堵塞。考虑使用java.net.URI来代替。
8.
Dm: Method invokes inefficient Boolean constructor; use Boolean.valueOf(…) instead (DM_BOOLEAN_CTOR)
使用new方法创建一个java.lang.Boolean类型能够的实例对象是浪费空间的,因为Boolean对象是不可变的而且只有两个有用的值。使用Boolean.valueOf()或者Java1.5中的自动装箱功能来创建一个Boolean实例。
9.
Dm: Explicit garbage collection; extremely dubious except in benchmarking code (DM_GC)
在代码中显式的调用垃圾回收命名,这样做并不能起作用。在过去,有人在关闭操作或者finalize方法中调用垃圾回收方法导致了很多的性能浪费。这样大规模回收对象时会造成处理器运行缓慢。
10.
Dm: Use the nextInt method of Random rather than nextDouble to generate a random integer (DM_NEXTINT_VIA_NEXTDOUBLE)
如果r是一个java.util.Random对象,你可以使r.nextInt(n)生成一个0到n-1之前的随机数,而不是使用(int)(r.nextDouble() * n)
11.
Dm: Method invokes inefficient new String(String) constructor (DM_STRING_CTOR)
使用java.lang.String(String)构造函数会浪费内存因为这种构造方式和String作为参数在功能上容易混乱。只是使用String直接作为参数的形式
12.
Dm: Method invokes toString() method on a String (DM_STRING_TOSTRING)
调用String.toString()是多余的操作,只要使用String就可以了。
13.
Dm: Method invokes inefficient new String() constructor (DM_STRING_VOID_CTOR)
使用没有参数的构造方法去创建新的String对象是浪费内存空间的,因为这样创建会和空字符串“”混淆。Java中保证完成相同的构造方法会产生描绘相同的String对象。所以你只要使用空字符串来创建就可以了。
14.
ITA: Method uses toArray() with zero-length array argument (ITA_INEFFICIENT_TO_ARRAY)
当使用集合的toArray()方法时使用数组长度为0的数组作为参数。比这更有效的一种方法是
myCollection.toArray(new Foo[myCollection.size()]),如果数组的长度足够大就可以直接把集合中的内容包装到数组中直接返回从而避免了第二次创建一个新的数组来存放集合中值。
15.
SBSC: Method concatenates strings using + in a loop (SBSC_USE_STRINGBUFFER_CONCATENATION)
在循环中构建一个String对象时从性能上讲使用StringBuffer来代替String对象
例如:
// This is bad
String s = ”";
for (int i = 0; i < field.length; ++i)
s = s + field[i];
// This is better
StringBuffer buf = new StringBuffer();
for (int i = 0; i < field.length; ++i)
buf.append(field[i]);
String s = buf.toString();
16.
SS: Unread field: should this field be static? (SS_SHOULD_BE_STATIC)
类中所包含的final属性字段在编译器中初始化为静态的值。考虑在定义时就把它定义为static类型的。
17.
UM: Method calls static Math class method on a constant value (UM_UNNECESSARY_MATH)
在方法中使用了java.lang.Math的静态方法代替常量来使用,使用常量速度和准确度会更好。 以下为Math中的方法产生的值。
Method Parameter
abs -any-
acos 0.0 or 1.0
asin 0.0 or 1.0
atan 0.0 or 1.0
atan2 0.0 cbrt 0.0 or 1.0
ceil -any-
cos 0.0
cosh 0.0
exp 0.0 or 1.0
expm1 0.0
floor -any-
log 0.0 or 1.0
log10 0.0 or 1.0
rint -any-
round -any-
sin 0.0
sinh 0.0
sqrt 0.0 or 1.0
tan 0.0
tanh 0.0
toDegrees 0.0 or 1.0
toRadians 0.0
18.
UPM: Private method is never called (UPM_UNCALLED_PRIVATE_METHOD)
定义为Private类型方法从未被调用,应该被删除。
19.
UrF: Unread field (URF_UNREAD_FIELD)
类中定义的属性从未被调用,建议删除。
20.
UuF: Unused field (UUF_UNUSED_FIELD)
类中定义的属性从未被使用,建议删除。
21.
WMI: Inefficient use of keySet iterator instead of entrySet iterator (WMI_WRONG_MAP_ITERATOR)
当方法中接受一个Map类型的参数时,使用keySet的迭代器比使用entrySet的迭代器效率要高。
Internationalization关于代码国际化相关方面的
Dm: Consider using Locale parameterized version of invoked method (DM_CONVERT_CASE)
使用平台默认的编码格式对字符串进行大小写转换,这可能导致国际字符的转换不当。使用以下方式对字符进行转换
String.toUpperCase( Locale l )
String.toLowerCase( Locale l )
Multithreaded correctness关于代码多线程正确性相关方面的
序号
Description
备注
1.
DL: Synchronization on Boolean could lead to deadlock (DL_SYNCHRONIZATION_ON_BOOLEAN)
该代码同步一个封装的原始常量,例如一个Boolean类型。
private static Boolean inited = Boolean.FALSE;
…
synchronized(inited)
if (!inited)
init();
inited = Boolean.TRUE;
…
由于通常只存在两个布尔对象,此代码可能是同步的其他无关的代码中相同的对象,这时会导致反应迟钝和可能死锁
2.
DL: Synchronization on boxed primitive could lead to deadlock (DL_SYNCHRONIZATION_ON_BOXED_PRIMITIVE)
该代码同步一个封装的原始常量,例如一个Integer类型。
private static Integer count = 0;
…
synchronized(count)
count++;
…
由于Integer对象可以共享和保存,此代码可能是同步的其他无关的代码中相同的对象,这时会导致反应迟钝和可能死锁
3.
DL: Synchronization on interned String could lead to deadlock (DL_SYNCHRONIZATION_ON_SHARED_CONSTANT)
同步String类型的常量时,由于它被JVM中多个其他的对象所共有,这样在其他代码中会引起死锁。
4.
DL: Synchronization on boxed primitive values (DL_SYNCHRONIZATION_ON_UNSHARED_BOXED_PRIMITIVE)
同步一个显然不是共有封装的原始值,例如一个Integer类型的对象。例如:
private static final Integer fileLock = new Integer(1);
…
synchronized(fileLock)
.. do something ..
…
它最后被定义为以下方式来代替:private static final Object fileLock = new Object();
5.
Dm: Monitor wait() called on Condition (DM_MONITOR_WAIT_ON_CONDITION)
方法中以java.util.concurrent.locks.Condition对象调用wait()。等待一个条件发生时应该使用在Condition接口中定义的await()方法。
6.
Dm: A thread was created using the default empty run method (DM_USELESS_THREAD)
这个方法没有通过run方法或者具体声明Thread类,也没有通过一个Runnable对象去定义一个线程,而这个线程出来浪费资源却什么也没有去做。
7.
ESync: Empty synchronized block (ESync_EMPTY_SYNC)
该代码包含一个空的同步块:synchronized()
8.
IS: Inconsistent synchronization (IS2_INCONSISTENT_SYNC)
不合理的同步
9.
IS: Field not guarded against concurrent access (IS_FIELD_NOT_GUARDED)
域不是良好的同步访问—
此字段被标注为net.jcip.annotations.GuardedBy,但可以在某种程度上违反注释而去访问
10.
JLM: Synchronization performed on Lock (JLM_JSR166_LOCK_MONITORENTER)
实现java.util.concurrent.locks.Lock的对象调用了同步的方法。应该这样处理,对象被锁定/解锁时使用acquire()/ release()方法而不是使用同步的方法。
11.
LI: Incorrect lazy initialization of static field (LI_LAZY_INIT_STATIC)
静态域不正确的延迟初始化–
这种方法包含了一个不同步延迟初始化的非volatile静态字段。因为编译器或处理器可能会重新排列指令,如果该方法可以被多个线程调用,线程不能保证看到一个完全初始化的对象。你可以让字段可变来解决此问题
12.
LI: Incorrect lazy initialization and update of static field (LI_LAZY_INIT_UPDATE_STATIC)
这种方法包含一个不同步延迟初始化的静态字段。之后为字段赋值,对象存储到该位置后进一步更新或访问。字段后尽快让其他线程能够访问。如果该方法的进一步访问该字段为初始化对象提供服务,然后你有一个非常严重的多线程bug,除非别的东西阻止任何其他线程访问存储的对象,直到它完全初始化。
即使你有信心,该方法是永远不会被多个线程调用时,在它的值还没有被充分初始化或移动,不把它设定为static字段时它可能会更好。
13.
ML: Method synchronizes on an updated field (ML_SYNC_ON_UPDATED_FIELD)
对象获取一个可变字段时进行同步。这是没有意义的,因为不同的线程可以在不同的对象同步。
14.
MSF: Mutable servlet field (MSF_MUTABLE_SERVLET_FIELD)
一个web服务一般只能创建一个servlet或者jsp的实例(例如:treates是一个单利类),它会被多个线程调用这个实例的方法服务于多个同时的请求。因此使用易变的字段属性产生竞争的情况。
15.
MWN: Mismatched notify() (MWN_MISMATCHED_NOTIFY)
此方法调用Object.notify()或Object.notifyAll()而没有获取到该对象的对象锁。调用notify()或notifyAll()而没有持有该对象的对象锁,将导致IllegalMonitorStateException异常。
以上是关于FindBugs1.3.9规则整理的主要内容,如果未能解决你的问题,请参考以下文章
高级JAVA开发必备技能:时区的规则发生变化时,如何同步JDK的时区规则(实战方案,建议收藏)