Wild card in java Generic and <? super T> meaning, lower or upper bound

wildcard generics java
java wildcard vs generic
java generics
bounded wildcards in generics in java
difference between ? (wildcard and generic type java)
unbounded wildcard in java
java generics wildcard return type
java generic method

So I am reading about generic method and I am get confused. Let me state the problem here first:

In this example: Suppose that I need a version of selectionSort that works for any type T, by using an external comparable supplied by the caller.

First attempt:

public static <T> void selectionSort(T[] arr, Comparator<T> myComparator){....}

Suppose that I have:

  • Defined vehicle class
  • created VehicleComparator implementing Comparator while compare vehicles by their price.
  • created Truck extends vehicle
  • instantiated Truck[] arr ; VehicleComparator myComparator

Now, I do:

selectionSort(arr, myComparator);

and it won't work, because myComparator is not available for any subclass of Vehicle.

Then, I do this:

public static <T> void selectionSort(T[] arr, Comparator<? super T> myComparator){....}

This declaration will work, but I don't completely sure what I've been doing... I know use is the way to go. If "? super T" means "an unknown supertype of T", then am I imposing a upper or lower bound? Why is it super? My intention is to let any subclass of T to use myComparator, why "? super T". So confused... I'd appreciate if you have any insight in this..

Thanks ahead!


Firstly, you could have solved it by having Vehicle[] which you then added Trucks to.

The reason you need <? super T> goes back to the generics rule that Comparator<Truck> is not a subtype of Comparator<Vehicle>; the unbounded type T must match exactly, which it doesn't.

In order for a suitable Comparator to be passed in, it must be a Comparator of the class being compared or any super class of it, because in OO languages any class may be treated as an instance of a superclass. Thus, it doesn't matter what the generic type of the Comparator is, as long as it's a supertype of the array's component type.

Wildcards (The Java™ Tutorials > Bonus > Generics), The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later  This Java tutorial describes generics, full screen mode API, and Java certification related resources extends Shape> is an example of a bounded wildcard.


The quizzical phrase ? super T means that the destination list may have elements of any type that is a supertype of T, just as the source list may have elements of any type that is a subtype of T.

We can see pretty simple example copy from Collections:

public static <T> void copy(List<? super T> dst, List<? extends T> src) {
   for (int i = 0; i < src.size(); i++) {
    dst.set(i, src.get(i));
   }
}

And call:

List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
Collections.copy(objs, ints);
assert objs.toString().equals("[5, 6, four]");

As with any generic method, the type parameter may be inferred or may be given explicitly. In this case, there are four possible choices, all of which type-check and all of which have the same effect:

Collections.copy(objs, ints);
Collections.<Object>copy(objs, ints);
Collections.<Number>copy(objs, ints);
Collections.<Integer>copy(objs, ints);

Wildcards (The Java™ Tutorials > Learning the Java Language , In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a​  Java Generics - Guidelines for Wildcard Use - Wildcards can be used in three ways −


Java Generic's Wildcards, In order to decide which type of wildcard best suits the condition, let's first classify the type of parameters passed to a method as in and out parameter. in variable −​  Saying that GenericType<T> is invariant over T means: The relationship between Animals and Cats doesn’t matter; GenericType<Animal> has (almost) nothing to do with Generic<Cat>. In java, we can


The two signatures are equivalent in terms of power -- for any set of arguments, if there exists a choice of type arguments that works for one of them, there exists a choice of type arguments that works for the other one, and vice versa.

You are simply running into limited inference in your compiler. Simply explicitly specify the desired type argument:

YourClass.<Vehicle>selectionSort(arr, myComparator);

Java Generics - Guidelines for Wildcard Use, Java Generics - Unbounded Wildcards - The question mark (?), represents the wildcard, stands for unknown type in generics. There may be times when any  n generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type.


Java Generics - Unbounded Wildcards, This allows objects of type Generic<Supertype> and Generic<Subtype> to be safely assigned to a variable or method  Java Generics Wildcards usage is governed by the GET-PUT Principle (Which is also known as the IN-OUT principle). This states that: Use an "extends" wildcard when you only get values out of a structure, Use a "super" wildcard when you only put values into a structure, and do not use wildcards when you do both.


Wildcard (Java), In your first question, <? extends T> and <? super T> are examples of bounded wildcards. An unbounded wildcard looks like <?>  If you have only one parameterized type argument, then you can use wildcard, although type parameter will also work. Type parameters support multiple bounds, wildcards don't. Wildcards support both upper and lower bounds, type parameters just support upper bounds.


Java Generics (Wildcards), Starting with invariance and covariance. TLDR: 1) In java, List<Cat> is not a subtype of List<Animal>. This is annoying but safe. In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).