1. “.equals()” should not be used to test the values of “Atomic” classes
级别:bug
AtomicInteger, and AtomicLong extend Number, but they’re distinct from Integer and Long and should be handled differently. AtomicInteger and AtomicLong are designed to support lock-free, thread-safe programming on single variables. As such, an AtomicInteger will only ever be “equal” to itself. Instead, you should .get() the value and make comparisons on it.
This applies to all the atomic, seeming-primitive wrapper classes: AtomicInteger, AtomicLong, and AtomicBoolean.
Noncompliant Code Example
AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);
if (aInt1.equals(aInt2)) { ... } // Noncompliant
Compliant Solution
AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);
if (aInt1.get() == aInt2.get()) { ... }
Atomic
类相等与否的判断不能使用equals()
方法,Atomic
的作用为了在多线程情况下保持单个变量的线程安全性。Atomic
变量永远只会和自身相等,如果要判断Atomic
变量是否相等,应该使用get()
方法获取值之后再进行判断。
AtomicInteger
VSInteger
Integer
类重写了Object
的equals()
方法,根据值的大小判断是否相等:
/**
* Compares this object to the specified object. The result is
* {@code true} if and only if the argument is not
* {@code null} and is an {@code Integer} object that
* contains the same {@code int} value as this object.
*
* @param obj the object to compare with.
* @return {@code true} if the objects are the same;
* {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
而AtomicInteger
没有重写equals()
方法,当使用equals()
时,实际上使用的是Object
的equals()
方法,最终判断的是对象的地址是否相等。
public boolean equals(Object obj) {
return (this == obj);
}
Object
的equals()
描述:只有当x
和y
指向相同的引用时,equals()
才返回true
。
for any non-null reference values {@code x} and {@code y}, this method returns {@code true} if and only if {@code x} and {@code y} refer to the same object