Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generic with bounded wildcards

Tags:

java

generics

What is the difference between the class declarations

public abstract class Super1<T extends Super1<T>> {...}  

and

public abstract class Super2<T extends Super2<? super T>> {...}

Using the 1st method, I was able to create a sub classes (similar to Enum types in Java)

public class Sub1 extends Super1<Sub1> {...}

but I wanted to know if a super class declaration like 2nd is possible at all.., is there any meaning to it, but I was not able to create a sub class like

public class Sub2 extends Super2<Object> {...}

I thought Object can be used as super type for T?? Also another form I can think of is

public abstract class Super3<T extends Super3<? extends T>>

I am trying to learn generics and any help is appreciated.

like image 612
JKV Avatar asked May 30 '26 20:05

JKV


1 Answers

Those kinds of declaration often comes into picture when you are dealing with self-referential generic types with inheritance. The keywords here are - Self-Referential, and inheritance.

Let us understand this with an example. Suppose we have a class Car which implements a Comparable<Car>, and a subclass of Car - Mercedes:

class Car implements Comparable<Car> { ... }
class Mercedes extends Car { }

Now, you would also want the Mercedes to be comparable, so you might think that let's implement a Comparable<Mercedes> there, and the you do:

class Mercedes extends Car implements Comparable<Mercedes> { }

.. and there is where you get an error. Issue is that, now Mercedes class implements both Comparable<Car> and Comparable<Mercedes>, which is not allowed.

Futher Read on this:

  • Can a class implement different instantiations of the same generic interface?

So, you remove that Comparable<Mercedes> from there. Now you're left with Mercedes class implementing Comparable<Car>.

then you create a class, which uses self-referential type parameter like this:

class Garage<T extends Comparable<T>> { }

And while creating an instance of that, with both Car and Mercedes, you do like this:

Garage<Car> carComp = new Garage<Car>();
Garage<Mercedes> mercedesComp = new Garage<Mercedes>();

Can you spot the error? Yes there it is in the 2nd declaration. Mercedes type argument can not be used, because it doesn't satisfy the bounds T extends Comparable<T>. As Mercedes implements a Comparable<Car>. So what to do now?

Here comes the use of that declaration. Let's change your class Garage to something like this:

class Garage<T extends Comparable<? super T>> { }

.. and then your 2 instantiation will pass successfully, as now Mercedes satisfies the bounds.

like image 68
Rohit Jain Avatar answered Jun 02 '26 11:06

Rohit Jain