Shamveel Ahammed Shamveel Ahammed - 6 months ago 5
Java Question

How does Java's generics work?

Could anyone please help me understand how does Java's generics work? I understand the concept of it. But for this specific example of the code I don't clearly understand the compiler's error messages.

Example code:
Test class

// Test code
public class A < ListType extends Comparable < ListType >> {
// To make the instance variable y
public int y;
// To make the instance variable s
public String s;

//Constructor Method
public A(int requiredY, String requiredS) {
y = requiredY;
s = requiredS;

more code here...

Then in a different class I wrote

List <A> a = new ArrayList<A>();
more code here...

The error message I am getting is error: no suitable method found for sort(List<A>)
method Collections.<T#1>sort(List<T#1>) is not applicable
(inference variable T#1 has incompatible bounds
equality constraints: A
upper bounds: Comparable<? super T#1>)
method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
(cannot infer type-variable(s) T#2
(actual and formal argument lists differ in length))

where T#1,T#2 are type-variables:

T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)

I don't understand why is the compiler complaining about the type parameter. Shouldn't the collections work? Because the type parameters are both mutually comparable.


Your issue is that A is not Comparable. Notice your type signature:

public class A<ListType extends Comparable<ListType>>

This says that A (which is a poor name for a concrete class, single-letter types are generally reserved for generic types) has a generic type ListType, and that ListType is Comparable with other ListType objects.

The signature of Collections.sort() expects to be passed a List<T> where T is a generic type that implements Comparable. Since A does not implement Comparable you cannot pass it to Collections.sort().

You likely did not mean to define A the way you did. You probably intended to do something like this:

public class A<ListType> implements Comparable<A>

This says both that A has a generic type called ListType and that A implements Comparable and therefore can be compared (and sorted) with other instances of A.

Since A now implements the Comparable interface you'll need to define a compareTo() method on A.