rspec/rules/S2200/java/rule.adoc

94 lines
2.7 KiB
Plaintext

== Why is this an issue?
Assuming that a comparator or `compareTo` method always returns -1 or 1 if the first operand is less than or greater than the second is incorrect.
The specifications for both methods, `Comparator.compare` and `Comparable.compareTo`, state that their return value is "a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object."
Even if a specific comparator always returns -1, 0, or 1, this is only an implementation detail, not the API contract developers can rely on.
== How to fix it
Replace
- `== -1` with `< 0` (the first operand is less than the second)
- `== 1` with `> 0` (the first operand is greater than the second)
- `!= -1` with `>= 0` (the first operand is greater than or equal to the second)
- `!= 1` with `\<= 0` (the first operand is less than or equal to the second)
=== Code examples
==== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public class Main {
boolean isAGreaterThanB(Comparable<Integer> a, Integer b) {
return a.compareTo(b) == 1; // Noncompliant, check for constant return value
}
public static void main(String[] args) {
ByteComparator comparator = new ByteComparator();
if (comparator.compare((byte) 23, (byte) 42) == -1) { // Noncompliant, check for constant return value
System.out.println("23 < 42");
} else {
System.out.println("23 >= 42");
}
}
static class ByteComparator implements Comparator<Byte> {
@Override
public int compare(Byte a, Byte b) {
return a - b;
}
}
}
----
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
public class Main {
boolean isAGreaterThanB(Comparable<Integer> a, Integer b) {
return a.compareTo(b) > 0; // Compliant, check for positive return value
}
public static void main(String[] args) {
ByteComparator comparator = new ByteComparator();
if (comparator.compare((byte) 23, (byte) 42) < 0) { // Compliant, check for negative return value
System.out.println("23 < 42");
} else {
System.out.println("23 >= 42");
}
}
static class ByteComparator implements Comparator<Byte> {
@Override
public int compare(Byte a, Byte b) {
return a - b;
}
}
}
----
== Resources
=== Documentation
* https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T-[Java SE 8 API Specification: Comparable.compareTo]
* https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#compare-T-T-[Java SE 8 API Specification: Comparator.compare]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Only the sign of the result should be examined.
endif::env-github,rspecator-view[]