zoukankan      html  css  js  c++  java
  • Sonar rule for bug

     

    "equals(Object obj)" and "hashCode()" should be overridden in pairs

     

    According to the Java Language Specification, there is a contract between equals(Object) and hashCode():

    If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

    In order to comply with this contract, those methods should be either both inherited, or both overridden.

    Noncompliant Code Example

    class MyClass {    // Non-Compliant - should also override "hashCode()"
    
      @Override
      public boolean equals(Object obj) {
        /* ... */
      }
    
    }
    

    Compliant Solution

    class MyClass {    // Compliant
    
      @Override
      public boolean equals(Object obj) {
        /* ... */
      }
    
      @Override
      public int hashCode() {
        /* ... */
      }
    
    }

    "equals(Object obj)" should be overridden along with the "compareTo(T obj)" method

     

    According to the Java Comparable.compareTo(T o) documentation:

    It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the 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 the PriorityQueue.remove() method relied on compareTo(), but since Java 6 it relies on equals().

    Noncompliant Code Example

    public class Foo implements Comparable<Foo> {
      @Override
      public int compareTo(Foo foo) { /* ... */ }      // Noncompliant as the equals(Object obj) method is not overridden
    }
    

    Compliant Solution

    public class Foo implements Comparable<Foo> {
      @Override
      public int compareTo(Foo foo) { /* ... */ }      // Compliant
    
      @Override
      public boolean equals(Object obj) { /* ... */ }
    }
    
     

    Execution of the Garbage Collector should be triggered only by the JVM

     

    Calling System.gc() or Runtime.getRuntime().gc() is a bad idea for a simple reason: there is no way to know exactly what will be done under the hood by the JVM because the behavior will depend on its vendor, version and options:

    • Will the whole application be frozen during the call?
    • Is the -XX:DisableExplicitGC option activated?
    • Will the JVM simply ignore the call?
    • ...

    An application relying on those unpredictable methods is also unpredictable and therefore broken.

    The task of running the garbage collector should be left exclusively to the JVM.

     

    Loop counters should not be assigned to from within the loop body

     

    Loop counters should not be modified in the body of the loop. However other loop control variables representing logical values may be modified in the loop, for example a flag to indicate that something has been completed, which is then tested in the for statement.

    The following code:

    String[] names = new String[]{ "Jack", "Jim", null, "John" };
    for (int i = 0; i < names.length; i++) {
      if (names[i] == null) {
        i = names.length;                                             // Non-Compliant
      } else {
        System.out.println(names[i]);
      }
    }
    

    should be refactored into:

    String[] names = new String[]{ "Jack", "Jim", null, "John" };
    for (String name: names) {
      if (name == null) {
        break;                                                        // Compliant
      }
      System.out.println(name);
    }
    
     

    Nested blocks of code should not be left empty

     

    Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed. When a block contains a comment, this block is not considered to be empty.

    The following code snippet illustrates this rule:

    void doSomething() {
      for (int i = 0; i < 42; i++)        // Non-Compliant
      {
      }
      for (int i = 0; i < 42; i++);       // Compliant
    
      if (myVar == 4)                     // Compliant - contains a comment
      {
        // Do nothing because of X and Y
      }
      else                                // Compliant
      {
        doSomething();
      }
    
      try                                 // Non-Compliant
      {
      }
      catch (Exception e)                 // Compliant
      {
        // Ignore
      }
    }
    
     

    Return statements should not occur in finally blocks

     

    Returning from a finally block suppresses the propagation of any unhandled Throwable which was thrown in the try or catch block.

    The following code snippet illustrates this rule. The developer expects to get "ERROR" in the console whereas "OK" is displayed.

    public static void main(String[] args) {
      try {
        doSomethingWhichThrowsException();
        System.out.println("OK");
      } catch (RuntimeException e) {
        System.out.println("ERROR");
      }
    }
    
    public static void doSomethingWhichThrowsException() {
      try {
        throw new RuntimeException();
      } finally {
        /* ... */
        return;                                        // Non-Compliant - prevents the RuntimeException from being propagated
      }
    }
    
     

    Strings should be compared using equals()

     

    String literals, just like any other Object, should be compared using the equals() method. Using == and != does not work in general.

    The following code:

    if (variable == "foo") { /* ... */ }         // Non-Compliant
    if (variable != "foo") { /* ... */ }         // Non-Compliant
    

    should be refactored into:

    if ("foo".equals(variable)) { /* ... */ }    // Compliant
    if (!"foo".equals(variable)) { /* ... */ }   // Compliant
    
     

    super.finalize() should be called at the end of Object.finalize() implementations

     

    Overriding the Object.finalize() method must be done with caution to dispose some system resources. Calling the super.finalize() at the end of this method implementation is highly recommended in case parent implementations must also dispose some system resources.

    The following code snippet illustrates this rule:

    protected void finalize() {            // Non-Compliant
      releaseSomeResources();
    }
    
    protected void finalize() {
      super.finalize();                    // Non-Compliant
      releaseSomeResources();
    }
    
    protected void finalize() {
      releaseSomeResources();
      super.finalize();                    // Compliant
    }
    
  • 相关阅读:
    hihoCoder#1128 二分·二分查找
    hihoCoder#1127 二分图三·二分图最小点覆盖和最大独立集
    hihoCoder#1122 二分图二•二分图最大匹配之匈牙利算法
    hihoCoder#1105 题外话·堆
    Ajax详细剖析
    web框架之--Tornado
    web框架之--先来个介绍
    前端之--Jquery-玩穿它!
    前端之--DOM详解应用
    前端之--JavaScript作用域--超细讲解
  • 原文地址:https://www.cnblogs.com/davidwang/p/3680446.html
Copyright © 2011-2022 走看看