1、sonar规则适用未理解到位1. .equals() should not be used to test the values of Atomic classesAtomicInteger, andAtomicLongextendNumber, but theyre distinct fromIntegerandLongand should be handled differently.AtomicIntegerandAtomicLongare designed to support lock-free, thread-safe programming on single variables
2、. As such, anAtomicIntegerwill 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, andAtomicBoolean.Noncompliant Code ExampleAtomicInteger aInt1 = new AtomicInteger(0);
3、AtomicInteger aInt2 = new AtomicInteger(0);if (aInt1.equals(aInt2) . / NoncompliantCompliant SolutionAtomicInteger aInt1 = new AtomicInteger(0);AtomicInteger aInt2 = new AtomicInteger(0);if (aInt1.get() = aInt2.get() . .equals() 不应该用来测试Atomic类型的等值比较。3.BigDecimal(double) should not be usedBecause of
4、floating point imprecision, youre unlikely to get the value you expect from theBigDecimal(double)constructor.Fromthe JavaDocs:The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (a
5、n unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to
6、 the constructor is not exactly equal to 0.1, appearances notwithstanding.Instead, you should useBigDecimal.valueOf, which uses a string under the covers to eliminate floating point rounding errors.Noncompliant Code Exampledouble d = 1.1;BigDecimal bd1 = new BigDecimal(d); / Noncompliant; see commen
7、t aboveBigDecimal bd2 = new BigDecimal(1.1); / Noncompliant; same resultCompliant Solutiondouble d = 1.1;BigDecimal bd1 = BigDecimal.valueOf(d);BigDecimal bd2 = BigDecimal.valueOf(1.1);SeeCERT, NUM10-J- Do not construct BigDecimal objects from floating-point literals数值正确使用7. compareTo results should
8、 not be checked for specific valuesWhile mostcompareTomethods return -1, 0, or 1, some do not, and testing the result of acompareToagainst a specific value other than 0 could result in false negatives.Noncompliant Code Exampleif (myCpareTo(arg) = -1) / Noncompliant / .Compliant Solutionif (myCpareTo
9、(arg) 0) / .compareTo 不应该与具体的值做检查。 8. compareTo should not return Integer.MIN_VALUEIt is the sign, rather than the magnitude of the value returned fromcompareTothat matters. ReturningInteger.MIN_VALUEdoes not convey a higher degree of inequality, and doing so can cause errors because the return valu
10、e ofcompareTois sometimes inversed, with the expectation that negative values become positive. However, inversingInteger.MIN_VALUEyieldsInteger.MIN_VALUErather thanInteger.MAX_VALUE.Noncompliant Code Examplepublic int compareTo(MyClass) if (condition) return Integer.MIN_VALUE; / Noncompliant Complia
11、nt Solutionpublic int compareTo(MyClass) if (condition) return -1; 状态值不应该用数值类型的边界值。10. DateUtils.truncate from Apache Commons Lang library should not be usedThe use of theInstantclass introduced in Java 8 to truncate a date can be significantly faster than theDateUtilsclass from Commons Lang.Noncomp
12、liant Code Examplepublic Date trunc(Date date) return DateUtils.truncate(date, Calendar.SECOND); / Noncompliant Compliant Solutionpublic Date trunc(Date date) Instant instant = date.toInstant(); instant = instant.truncatedTo(ChronoUnit.SECONDS); return Date.from(instant);DateUtils.truncate 正确使用, 不建议
13、使用从效率上考虑的。12. Double.longBitsToDouble should not be used for intDouble.longBitsToDoubleexpects a 64-bit,longargument. Pass it a smaller value, such as anintand the mathematical conversion into adoublesimply wont work as anticipated because the layout of the bits will be interpreted incorrectly, as i
14、f a child were trying to use an adults gloves.Noncompliant Code Exampleint i = 42;double d = Double.longBitsToDouble(i); / NoncompliantDouble.longBitsToDouble()方法不建议被使用13. entrySet() should be iterated when both the key and value are neededWhen only the keys from a map are needed in a loop, iteratin
15、g thekeySetmakes sense. But when both the key and the value are needed, its more efficient to iterate theentrySet, which will give access to both the key and value, instead.Noncompliant Code Examplepublic void doSomethingWithMap(Map map) for (String key : map.keySet() / Noncompliant Object value = m
16、ap.get(key); / . Compliant Solutionpublic void doSomethingWithMap(Map map) for (Map.Entry entry : map.entrySet() String key = entry.getKey(); Object value = entry.getValue(); / . “entryset()”应该是迭代时,键和值是必要的keySet是键的集合,Set里面的类型即key的类型entrySet是 键-值 对的集合,Set里面的类型是Map.Entry14. equals methods should be sy
17、mmetric and work for subclassesA key facet of theequalscontract is that ifa.equals(b)thenb.equals(a), i.e. that the relationship is symmetric.Usinginstanceofbreaks the contract when there are subclasses, because while the child is aninstanceofthe parent, the parent is not anintanceofthe child. For i
18、nstance, assume thatRaspberry extends Fruitand adds some fields (requiring a new implementation ofequals):Fruit fruit = new Fruit();Raspberry raspberry = new Raspberry();if (raspberry instanceof Fruit) . / trueif (fruit instanceof Raspberry) . / falseIf similarinstanceofchecks were used in the class
19、esequalsmethods, the symmetry principle would be broken:raspberry.equals(fruit); / falsefruit.equals(raspberry); /trueAdditionally, nonfinalclasses shouldnt use a hardcoded class name in theequalsmethod because doing so breaks the method for subclasses. Instead, make the comparison dynamic.Further,
20、comparing to an unrelated class type breaks the contract for that unrelated type, because whilethisClass.equals(unrelatedClass)can return true,unrelatedClass.equals(thisClass)will not.Noncompliant Code Examplepublic class Fruit extends Food private Season ripe; public boolean equals(Object obj) if (
21、obj = this) return true; if (Fruit.class = obj.getClass() / Noncompliant; broken for child classes return ripe.equals(Fruit)obj).getRipe(); if (obj instanceof Fruit ) / Noncompliant; broken for child classes return ripe.equals(Fruit)obj).getRipe(); else if (obj instanceof Season) / Noncompliant; sym
22、metry broken for Season class / . /.Compliant Solutionpublic class Fruit extends Food private Season ripe; public boolean equals(Object obj) if (obj = this) return true; if (this.getClass() = obj.getClass() return ripe.equals(Fruit)obj).getRipe(); return false;equals 子类也需要重写, equals 一个重要属性是, 如果a.equ
23、als(b)然后b.equals(A),即是对称的关系。建议使用此规则。16. equals(Object obj) should be overridden along with the compareTo(T obj) methodAccording to the JavaCpareTo(T o)documentation:It is strongly recommended, but not strictly required that(pareTo(y)=0) = (x.equals(y). Generally speaking, any class that implements t
24、he Comparable interface and violates this condition should clearly indicate this fact. The recommended language is Note: this class has a natural ordering that is inconsistent with equals.If this rule is violated, weird and unpredictable failures can occur. For example, in Java 5 thePriorityQueue.re
25、move()method relied oncompareTo(), but since Java 6 it relies onequals().Noncompliant Code Examplepublic class Foo implements Comparable Override public int compareTo(Foo foo) /* . */ / Noncompliant as the equals(Object obj) method is not overriddenCompliant Solutionpublic class Foo implements Compa
26、rable Override public int compareTo(Foo foo) /* . */ / Compliant Override public boolean equals(Object obj) /* . */ 使用 compareTo(T obj) 时 equals(Object obj) 也应该重写17.equals(Object obj) should test argument typeBecause the equals method takes a generic Object as a parameter, any type of object may be
27、passed to it. The method should not assume it will only be used to test objects of its class type. It must instead check the parameters type.Noncompliant Code Examplepublic boolean equals(Object obj) MyClass mc = (MyClass)obj; / Noncompliant / .Compliant Solutionpublic boolean equals(Object obj) if
28、(obj = null) return false; if (this.getClass() != obj.getClass() return false; MyClass mc = (MyClass)obj; / .equals(Object obj) 应该是检验参数类型是否为Object。23.hashCode and toString should not be called on array instancesWhile hashCode and toString are available on arrays, they are largely useless. hashCode r
29、eturns the arrays identity hash code, and toString returns nearly the same value. Neither methods output actually reflects the arrays contents. Instead, you should pass the array to the relevant static Arrays method.Noncompliant Code Examplepublic static void main( String args ) String argStr = args
30、.toString(); / Noncompliant int argHash = args.hashCode(); / NoncompliantCompliant Solutionpublic static void main( String args ) String argStr = Arrays.toString(args); int argHash = Arrays.hashCode(args);hashCode and toString 不应该被数组实例调用。27.instanceof operators that always return true or false should be removedinstanceof operators that always return true or false are either useless or the result of a misunderstanding which could lead to unexpected behavior in production.