rspec/rules/S1319/java/rule.adoc

94 lines
3.3 KiB
Plaintext

This rule raises an issue when a collection implementation class from `java.util.*` is used:
* as a return type of a `public` method.
* as an argument type of a `public` method.
* as the type of a `public` field.
== Why is this an issue?
The Java Collections API offers a well-structured hierarchy of interfaces
designed to hide collection implementation details.
For the various collection data structures like lists, sets, and maps,
specific interfaces (`java.util.List`, `java.util.Set`, `java.util.Map`)
cover the essential features.
When passing collections as method parameters, return values, or when exposing fields,
it is generally recommended to use these interfaces instead of the implementing classes.
The implementing classes, such as `java.util.LinkedList`, `java.util.ArrayList`,
and `java.util.HasMap`, should only be used for collection instantiation.
They provide finer control over the performance characteristics of those structures,
and developers choose them depending on their use case.
For example, if fast random element access is essential, `java.util.ArrayList` should be instantiated.
If inserting elements at a random position into a list is crucial, a `java.util.LinkedList` should be preferred.
However, this is an implementation detail your API should not expose.
=== Code examples
==== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
public class Employees {
public final HashSet<Employee> employees // Noncompliant, field type should be "Set"
= new HashSet<Employee>();
public HashSet<Employee> getEmployees() { // Noncompliant, return type should be "Set"
return employees;
}
}
----
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
public class Employees {
public final Set<Employee> employees // Compliant
= new HashSet<Employee>();
public Set<Employee> getEmployees() { // Compliant
return employees;
}
}
----
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
"XXX" should be an interface such as "YYY" rather than the implementation "ZZZ".
The return type of this method should be an interface such as "YYYY" rather than the implementation "ZZZ".
'''
== Comments And Links
(visible only on this page)
=== on 15 Oct 2013, 09:28:56 Freddy Mallet wrote:
Is implemented by \http://jira.codehaus.org/browse/SONARJAVA-360
=== on 10 Apr 2017, 00:26:42 ron190 wrote:
I changed LinkedList to List in my project but after 4 levels of changes that I applied successively to return types and parameter types, I encountered list.getLast() and list.removeLast() but those methods do not exist in interface List.
Is it right to use list.get(list.size()-1) instead of list.getLast() in term of performances and complexity ?
LinkedList keeps references to both head and tail and offers a complexity of O(1), is it the same with list.get(list.size()-1) ?
Posted to Groups (thank you Ann)
https://groups.google.com/forum/#!topic/sonarqube/jc0WU-8RE94
=== on 10 Apr 2017, 15:53:31 Ann Campbell wrote:
\[~ron190] this isn't the best place to initiate a discussion. You'll reach a broader audience if you go to the https://groups.google.com/forum/#!forum/sonarqube[SonarQube Google Group]
endif::env-github,rspecator-view[]