rspec/rules/S2159/java/rule.adoc
Fred Tingaud 6f24cc0632
Clean rule at root
In some cases, the `rule.adoc` at root of a rule is never included
anywhere and thus is dead code.
It's a maintenance cost by itself, but also it misses opportunities to
inline code that seems used by two documents when in fact only one
document is actually rendered. And this missed opportunity, in turn,
stops us from applying the correct language tag on the code samples.
2023-10-16 16:34:38 +02:00

82 lines
2.6 KiB
Plaintext

== Why is this an issue?
Comparisons of dissimilar types will always return false. The comparison and all its dependent code can simply be removed. This includes:
* comparing an object with null
* comparing an object with an unrelated primitive (E.G. a string with an int)
* comparing unrelated classes
* comparing an unrelated ``++class++`` and ``++interface++``
* comparing unrelated ``++interface++`` types
* comparing an array to a non-array
* comparing two arrays
Specifically in the case of arrays, since arrays don't override ``++Object.equals()++``, calling ``++equals++`` on two arrays is the same as comparing their addresses. This means that ``++array1.equals(array2)++`` is equivalent to ``++array1==array2++``.
However, some developers might expect ``++Array.equals(Object obj)++`` to do more than a simple memory address comparison, comparing for instance the size and content of the two arrays. Instead, the ``++==++`` operator or ``++Arrays.equals(array1, array2)++`` should always be used with arrays.
=== Noncompliant code example
[source,java]
----
interface KitchenTool { ... };
interface Plant {...}
public class Spatula implements KitchenTool { ... }
public class Tree implements Plant { ...}
//...
Spatula spatula = new Spatula();
KitchenTool tool = spatula;
KitchenTool [] tools = {tool};
Tree tree = new Tree();
Plant plant = tree;
Tree [] trees = {tree};
if (spatula.equals(tree)) { // Noncompliant; unrelated classes
// ...
}
else if (spatula.equals(plant)) { // Noncompliant; unrelated class and interface
// ...
}
else if (tool.equals(plant)) { // Noncompliant; unrelated interfaces
// ...
}
else if (tool.equals(tools)) { // Noncompliant; array & non-array
// ...
}
else if (trees.equals(tools)) { // Noncompliant; incompatible arrays
// ...
}
else if (tree.equals(null)) { // Noncompliant
// ...
}
----
== Resources
* https://wiki.sei.cmu.edu/confluence/x/5zdGBQ[CERT, EXP02-J.] - Do not use the Object.equals() method to compare two arrays
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
* Remove this call to "equals"; comparisons against null always return false.
* Remove this call to "equals"; comparisons between a type and an array always return false.
* Remove this call to "equals"; comparisons between an array and a type always return false.
* Use "Arrays.equals(array1, array2)" or the "==" operator instead of using the "Object.equals(Object obj)" method.
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]