Recipe Name:
Incorrect equality check of wrapper values (equals)
Description:
Use equals method to compare wrapped values
Level:
error
Language:
  • java
Tags:
  • Java basic
  • quality
  • SEI CERT
Documentation

Values contained in a not fully memoized wrapper class should be compared using the equals method of the wrapper instead of the reference comparison operator (==) to prevent unexpected results.

As an example, using the reference comparison operator for Long values in the range -128 to 127 will behave the same as the equals method. However, if we perform the same comparison with values outside this range, the results will differ. This is due to Java maintaining a constant pool for the mentioned range of Long values. Using the equals method will always yield the expected results and should be preferred.

Before
Long a = 1024L;
Long b = 1024L;
boolean areEqual = a == b;
boolean differ = a != b;
After
Long a = 1024L;
Long b = 1024L;
boolean areEqual = a.equals(b);
boolean differ = !a.equals(b);
References
Recipe
id: scw:java:equality-wrappers-equals
version: 10
metadata:
  name: Incorrect equality check of wrapper values (equals)
  shortDescription: Use equals method to compare wrapped values
  level: error
  language: java
  scwCategory: blog:generic
  cweCategory: 480
  enabled: true
  descriptionFile: descriptions/Incorrect_equality_check_of_wrapper_values.html
  tags: Java basic;quality;SEI CERT
search:
  comparison:
    first:
      expression:
        type:
          reference:
            matches: java\.lang\.(Character|Float|Integer|Long|Short|Double)
          checkInheritance: true
    operator: ==
    second:
      expression:
        type:
          reference:
            matches: java\.lang\.(Character|Float|Integer|Long|Short|Double)
          checkInheritance: true
availableFixes:
- name: Check equality using equals
  actions:
  - rewrite:
      to: '{{{leftOperand}}}.equals({{{rightOperand}}})'