This rule raises an issue when a collection implementation class from java.util.* is used:

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

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

public class Employees {
  public final Set<Employee> employees       // Compliant
    = new HashSet<Employee>();

  public Set<Employee> getEmployees() {      // Compliant
    return employees;
  }
}