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异常。



16.
MWN: Mismatched wait() (MWN_MISMATCHED_WAIT)
此方法调用Object.wait()而没有获取到该对象的对象锁。调用wait()而没有持有该对象的对象锁,将导致IllegalMonitorStateException异常。



17.
NP: Synchronize and null check on the same field. (NP_SYNC_AND_NULL_CHECK_FIELD)
如果代码块是同步的,那么久不可能为空。如果是空,同步时就会抛出NullPointerException异常。最好是在另一个代码块中进行同步。



18.
No: Using notify() rather than notifyAll() (NO_NOTIFY_NOT_NOTIFYALL)
调用notify()而不是notifyAll()方法。 Java的监控器通常用于多个条件。调用notify()只唤醒一个线程,这意味着该线程被唤醒只是满足的当前的唯一条件。



19.
RS: Class’s readObject() method is synchronized (RS_READOBJECT_SYNC)
序列化类中定义了同步的readObject()。通过定义,反序列化创建的对象只有一个线程可以访问,因此没有必要的readObject()进行同步。如果的readObject()方法本身造成对象对另一个线程可见,那么这本身就是不好的编码方式。



20.
Ru: Invokes run on a thread (did you mean to start it instead?) (RU_INVOKE_RUN)
这种方法显式调用一个对象的run()。一般来说,类是实现Runnable接口的,因为在一个新的线程他们将有自己的run()方法,在这种情况下Thread.start()方法调用是正确的。



21.
SC: Constructor invokes Thread.start() (SC_START_IN_CTOR)
在构造函数中启动一个线程。如果类曾经被子类扩展过,那么这很可能是错的,因为线程将在子类构造之前开始启动。



22.
SP: Method spins on field (SP_SPIN_ON_FIELD)
方法无限循环读取一个字段。编译器可合法悬挂宣读循环,变成一个无限循环的代码。这个类应该改变,所以使用适当的同步(包括等待和通知要求)



23.
STCAL: Call to static Calendar (STCAL_INVOKE_ON_STATIC_CALENDAR_INSTANCE)
即使JavaDoc对此不包含暗示,而Calendars本身在多线程中使用就是不安全的。探测器发现当调用Calendars的实例时将会获得一个静态对象。
Calendar rightNow = Calendar.getInstance();



24.
STCAL: Call to static DateFormat (STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE)
在官方的JavaDoc,DateFormats多线程使用本事就是不安全的。探测器发现调用一个DateFormat的实例将会获得一个静态对象。
myString = DateFormat.getDateInstance().format(myDate);
 



25.
STCAL: Static Calendar (STCAL_STATIC_CALENDAR_INSTANCE)
Calendar在多线程中本身就是不安全的,如果在线程范围中共享一个Calendarde 实例而不使用一个同步的方法在应用中就会出现一些奇怪的行为。在sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate()中会抛出ArrayIndexOutOfBoundsExceptions or IndexOutOfBoundsExceptions异常。



26.
STCAL: Static DateFormat (STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE)
DateFormat 在多线程中本身就是不安全的,如果在线程范围中共享一个DateFormat的实例而不使用一个同步的方法在应用中就会出现一些奇怪的行为。



27.
SWL: Method calls Thread.sleep() with a lock held (SWL_SLEEP_WITH_LOCK_HELD)
当持有对象时调用Thread.sleep()。这可能会导致很差的性能和可扩展性,或陷入死锁,因为其他线程可能正在等待获得锁。调用wait()是一个更好的主意,释放对象的持有以允许其他线程运行。



28.
UG: Unsynchronized get method, synchronized set method (UG_SYNC_SET_UNSYNC_GET)
这个类包含类似命名的get和set方法。在set方法是同步方法和get方法是非同步方法。这可能会导致在运行时的不正确行为,因为调用的get方法不一定返回对象一致状态。 GET方法应该同步。



29.
UL: Method does not release lock on all paths (UL_UNRELEASED_LOCK)
方法获得了当前的对象所,但是在方法中始终没有释放它。一个正确的示例如下:
Lock l = …;
l.lock();
try {
// do something
} finally {
l.unlock();
}



30.
UL: Method does not release lock on all exception paths (UL_UNRELEASED_LOCK_EXCEPTION_PATH)
方法获得了当前的对象所,但是在所有的异常处理中始终没有释放它。一个正确的示例如下:
Lock l = …;
l.lock();
try {
// do something
} finally {
l.unlock();
}



31.
UW: Unconditional wait (UW_UNCOND_WAIT)
方法中包含调用java.lang.Object.wait(),而却没有放到条件流程控制中。该代码应确认条件尚未满足之前等待;先前任何通知将被忽略。



32.
VO: A volatile reference to an array doesn’t treat the array elements as volatile (VO_VOLATILE_REFERENCE_TO_ARRAY)
声明一个变量引用数组,这可能不是你想要的。如果一个变量引用数组,那么对引用数组的读和写都是不安全的,但是数组元素不是变量。取得数组的变量值你可以使用java.util.concurrent包中的数组的原子性特性



33.
WL: Sychronization on getClass rather than class literal (WL_USING_GETCLASS_RATHER_THAN_CLASS_LITERAL)
实例的方法中同步this.getClass(),如果这个类有子类集合,那么子类集合中的对象将会在这个类的各个子类上进行同步,这不是我们想要的效果,我们只要同步当前的类对象而不包含它的所有子类,可以同步类名.getClass()。例如,java.awt.Label的代码:
private static final String base = ”label”;
private static int nameCounter = 0;
String constructComponentName() {
synchronized (getClass()) {
return base + nameCounter++;
}
}
Label中的子类集合不可能在同一个子对象上进行同步,替换上面的方法为:
private static final String base = ”label”;
private static int nameCounter = 0;
String constructComponentName() {
synchronized (Label.class) {
return base + nameCounter++;
}
}



34.
WS: Class’s writeObject() method is synchronized but nothing else is (WS_WRITEOBJECT_SYNC)
这个类有一个writeObject()方法是同步的,但是这个类中没有其他的同步方法。



35.
Wa: Condition.await() not in loop (WA_AWAIT_NOT_IN_LOOP)
方法没有在循环中调用java.util.concurrent.await()。如果对象是用于多种条件,打算调用wait()方法的条件可能不是实际发生的。



36.
Wa: Wait not in loop (WA_NOT_IN_LOOP)

这种方法包含调用java.lang.Object.wait(),而这并不是一个循环。如果监视器用于多个条件,打算调用wait()方法的条件可能不是实际发生的。


地址 : https://www.douban.com/note/282628929/?type=like

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值