Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-1201

"equals" method overrides should accept "Object" parameters

    XMLWordPrintable

    Details

    • Type: Bug Detection
    • Status: Active
    • Resolution: Unresolved
    • Labels:
    • Message:
      Either override Object.equals(Object), or totally rename the method to prevent any confusion.
    • Default Severity:
      Major
    • Impact:
      Low
    • Likelihood:
      High
    • Default Quality Profiles:
      Sonar way
    • Covered Languages:
      Java
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      10min
    • Analysis Scope:
      Main Sources, Test Sources
    • Checkstyle:
      CovariantEquals
    • FindBugs:
      EQ_SELF_NO_OBJECT, EQ_ABSTRACT_SELF, EQ_OTHER_NO_OBJECT, EQ_SELF_USE_OBJECT,EQ_DONT_DEFINE_EQUALS_FOR_ENUM, EQ_OTHER_USE_OBJECT
    • PMD:
      SuspiciousEqualsMethodName

      Description

      "equals" as a method name should be used exclusively to override Object.equals(Object) to prevent any confusion.

      It is tempting to overload the method to take a specific class instead of Object as parameter, to save the class comparison check. However, this will not work as expected when that is the only override.

      Noncompliant Code Example

      class MyClass {
        private int foo = 1;
      
        public boolean equals(MyClass o) {  // Noncompliant; does not override Object.equals(Object)
          return o != null && o.foo == this.foo;
        }
      
        public static void main(String[] args) {
          MyClass o1 = new MyClass();
          Object o2 = new MyClass();
          System.out.println(o1.equals(o2));  // Prints "false" because o2 an Object not a MyClass
        }
      }
      
      class MyClass2 {
        public boolean equals(MyClass2 o) {  // Ignored; `boolean equals(Object)` also present
          //..
        }
      
        public boolean equals(Object o) {
          //...
        }
      }
      

      Compliant Solution

      class MyClass {
        private int foo = 1;
      
        @Override
        public boolean equals(Object o) {
          if (this == o) {
              return true;
          }
          if (o == null || getClass() != o.getClass()) {
            return false;
          }
      
          MyClass other = (MyClass)o;
          return this.foo == other.foo;
        }
      
        /* ... */
      }
      
      class MyClass2 {
        public boolean equals(MyClass2 o) {
          //..
        }
      
        public boolean equals(Object o) {
          //...
        }
      }
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              freddy.mallet Freddy Mallet (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated: