94 lines
3.3 KiB
Plaintext
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[]
|