title: Covariant return type best practices
body: <p>I vaguely remember learning in university that the return type of a method should always be as narrow as possible, but my search for any references online came up empty and SonarQube calls it a code smell. E.g. in the following example (note that <code>TreeSet</code> and <code>Set</code> are just examples)</p>
  
  <pre><code>public interface NumberGetter {
      Number get();
  
      Set&lt;Number&gt; getAll();
  }
  
  public class IntegerGetter implements NumberGetter {
  
      @Override
      public Integer get() {
          return 1;
      }
  
      @Override
      public TreeSet&lt;Number&gt; getAll() {
          return new TreeSet&lt;&gt;(Collections.singleton(1));
      }
  }
  </code></pre>
  
  <p>SonarQube tells me</p>
  
  <blockquote>
    <p>Declarations should use Java collection interfaces such as "List" rather than specific implementation classes such as "LinkedList". The purpose of the Java Collections API is to provide a well defined hierarchy of interfaces in order to hide implementation details. (squid:S1319)</p>
  </blockquote>
  
  <p>I see the point about hiding implementation details, since I cannot easily change the return type of IntegerGetter::getAll() without breaking backwards-compatibility. But by doing this, I also provide the consumers with potentially valuable information, i.e. they could change their algorithm to be more appropriate for using a <code>TreeSet</code>. And if they don't care about this property, they can still just use <code>IntegerGetter</code> (however they obtained it), like this:</p>
  
  <pre><code>Set&lt;Number&gt; allNumbers = integerGetter.getAll();
  </code></pre>
  
  <p>So I have the following questions:</p>
  
  <ul>
  <li>Is it appropriate for IntegerGetter::get() to return a narrower type?</li>
  <li>Is it appropriate for IntegerGetter::getAll() to return a narrower type?</li>
  <li>Are there any best practices regarding this topic or is the answer just "it depends"?</li>
  </ul>
  
  <p>(N.B. SonarQube doesn't complain if I replace <code>TreeSet</code> with e.g. <code>SortedSet</code>. Is this code smell only about not using a Collection API interface? What if there is only a concrete class for my particular problem?)</p>