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
    }
    
  • 相关阅读:
    php+GTK2 学习第二篇
    PHPMailer + qq邮箱 实现邮件发送
    HTTP状态码200、301、403、404、500等(转)
    LNMP环境搭建(转载)
    PHP+GTK2 初体验,简单计算器客户端
    mysql 用户权限管理(转)
    提高php执行效率的10条编程习惯(转)
    添加php拓展(以phppcntl及phpredis及phppcntl为例)
    centos7 &后台运行 受终端关闭影响问题
    sklearn学习笔记之简单线性回归
  • 原文地址:https://www.cnblogs.com/davidwang/p/3680446.html
Copyright © 2011-2022 走看看