java:S7158 not raised when length() is compared to the hexadecimal literal 0x0

Product: SonarQube Community Build 26.5.0.122743
sonar-java version: sonar-java 8.29 (build 43460)
sonar-java SE version: sonar-java-symbolic-execution 8.16.4 (build 1912)
Java source level: 21 (javac 21, source/target 21)

Rule

java:S7158 — “isEmpty()” should be used to test for emptiness

Description

S7158 flags comparisons of CharSequence.length() (and StringBuilder / StringBuffer / String length()) against the constant 0, suggesting isEmpty() instead. The matcher keys on the decimal literal token 0 rather than on the constant integer value. Writing the identical value as the hexadecimal literal 0x0 produces the same int constant 0, but the rule no longer fires.

Reproducer

// BEFORE — S7158 raised twice
public class S7158Before {
  boolean testStringBuilder(StringBuilder sb) {
    return sb.length() == 0;     // Noncompliant
  }
  boolean testCharSequence(CharSequence cs) {
    return cs.length() == 0;     // Noncompliant
  }
}

// AFTER — semantically identical, S7158 NOT raised
public class S7158After {
  boolean testStringBuilder(StringBuilder sb) {
    return sb.length() == 0x0;   // no issue (FN)
  }
  boolean testCharSequence(CharSequence cs) {
    return cs.length() == 0x0;   // no issue (FN)
  }
}

Expected behavior

S7158 should be raised regardless of how the integer literal 0 is spelled. 0 and 0x0 denote the identical compile-time constant int value 0, so the length() == 0 anti-pattern is present in both forms.

Actual behavior

  • BEFORE: two java:S7158 (MINOR) issues, one per length() == 0.
  • AFTER: zero issues. Rewriting 0 as 0x0 suppresses the rule entirely.