简体   繁体   中英

Java Generic with bounded wildcards

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.

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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM