简体   繁体   中英

Java generic multiple bounds error:cannot be inherited with different type arguments

When I wrote the code, I thought about using generic multiple bounds to achieve a problem,but when I finished writing, it kept reporting errors:cannot be inherited with different type arguments

I have the following classes:

public class Animal implements Comparable<Animal> {}
public class Dog extends Animal   {}

I also defined a static method:

public static <T extends Animal & Comparable<? extends T>> T getMin(List<T> value) { return null;}

My idea is to define a generic type, this generic type must be a subclass of Animal, and this generic type must implement the Comparable interface, and the actual parameters of the interface are Annimal and its subclass class.

Later I made another attempt,defined another static method:

public static <T extends Animal & Comparable<? super T>> T getMin(List<T> value) { return null;}

My idea is to define a generic type, this generic type must be a subclass of Animal, and this generic type must implement the Comparable interface, and the actual parameters of the interface are Annimal and its parent class.

It is frustrating that both methods report errors: java.lang.Comparable' cannot be inherited with different type arguments: 'Animal' and 'capture

Finally, I found that the Animal and dog classes need to be modified as follows,just like number and its subclasses:

public class Animal  {}
public class Dog extends Animal implements Comparable<Dog>  {}

But I do n't understand why it needs to be modified like this, and why the error was reported at the beginning.

Java's generics are only known by the Java compiler, but not the JVM. This is known as type erasure . Comparable<Animal> and Comparable<Dog> are the same type, as far as the JVM is concerned. The JVM just thinks of both of them as Comparable .

This is invalid:

<T extends Animal & Comparable<? extends T>>

Because you are saying that T should implement two interfaces at the same time: Comparable<Animal> (since Animal implements Comparable<Animal> ) and Comparable<U> where U is a subclass of T . T can't implement these two interfaces at the same time, because although they look different to the compiler, the runtime thinks they are the same Comparable .

This is the same reason why you can't have Animal implement Comparable<Animal> and Dog implement Comparable<Dog> . Dog would be implementing two interfaces that look the same to the runtime!

You could say:

<T extends Animal & Comparable<Animal>>

but that's kind of redundant...

By making only Dog implement Comparable<Dog> , T extends Animal no longer implies T implements Comparable<Animal> , so you are no longer saying that T should implement 2 different interfaces.

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