== Why is this an issue? A return type containing wildcards cannot be narrowed down in any context. This indicates that the developer's intention was likely something else. The core problem lies in type variance. Expressions at an input position, such as arguments passed to a method, can have a more specific type than the type expected by the method, which is called _covariance_. Expressions at an output position, such as a variable that receives the return result from a method, can have a more general type than the method's return type, which is called _contravariance_. This can be traced back to the Liskov substitution principle. In Java, type parameters of a generic type are invariant by default due to their potential occurrence in both input and output positions at the same time. A classic example of this is the methods `T get()` (output position) and `add(T element)` (input position) in interface `java.util.List`. We could construct cases with invalid typing in `List` if `T` were not invariant. Wildcards can be employed to achieve covariance or contravariance in situations where the type parameter appears in one position only: - `` for covariance (input positions) - `` for contravariance (output positions) However, covariance is ineffective for the return type of a method since it is not an input position. Making it contravariant also has no effect since it is the receiver of the return value which must be contravariant (use-site variance in Java). Consequently, a return type containing wildcards is generally a mistake. == How to fix it The solution to this problem depends on the original intention of the developer. Given the examples: [source,java,diff-id=1,diff-type=noncompliant] ---- List getAnimals() { ... } // Noncompliant, wildcard with no use List getLifeforms() { ... } // Noncompliant, wildcard with no use ---- You can remove the wildcards to make the types invariant: [source,java,diff-id=1,diff-type=compliant] ---- List getAnimals() { ... } // Compliant, using invariant type instead List getLifeforms() { ... } // Compliant, using invariant type instead ---- Or replace them with a super- or subtypes (still invariant): [source,java] ---- List getAnimals() { ... } // Compliant, using subtype instead List getLifeforms() { ... } // Compliant, using supertype instead ---- == Resources === Documentation * https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html[The Java™ Tutorials - Wildcards] === Articles & blog posts * https://medium.com/javarevisited/variance-in-java-and-scala-63af925d21dc[Sinisa Louc - A Complete Guide to Variance in Java and Scala] * https://kotlinexpertise.com/kotlin-generics-and-variance-vs-java[Kotlin Expertise Blog - Kotlin Generics and Variance (Compared to Java)] * https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)[Wikipedia - Covariance and contravariance (computer science)] * https://schneide.blog/2015/05/11/declaration-site-and-use-site-variance-explained/[Schneide Blog - Declaration-site and use-site variance explained] * https://en.wikipedia.org/wiki/Liskov_substitution_principle[Wikipedia - Liskov substitution principle] ifdef::env-github,rspecator-view[] ''' == Implementation Specification (visible only on this page) === Message Remove usage of generic wildcard type ''' == Comments And Links (visible only on this page) === on 1 Nov 2013, 19:22:11 Freddy Mallet wrote: Is implemented by \https://jira.sonarsource.com/browse/SONARJAVA-374 endif::env-github,rspecator-view[]