How can I check if a Java generic type is a subclass of a comparator?
There is one case that needs to be handled when I try to complete the task: the exception from the generic class type is not comparable. See the following code for details.
public class C <T>
{
public C()
{
// throw exception if T is not comparable
}
}
You can enforce generic to be subclassed Comparator
like this:
public class C <T extends Comparator> {
public C(){
}
}
As you can see in the code below, it would be nice to add another generic one (here it is K
) that you point to Comparator
, since the generic parameter Comparator
will default to Object
.
public class C <K, T extends Comparator<K>> {
public C(){
}
}
Typically you use this in a form T x K
where T
is generic, x
is super
or extends
and K
is a class / interface.
Comparator docs
You have to make sure that the common parameter T is Comparable
by writing:
public class C <T extends Comparable>
There are two ways:
1) Make T extends Comparable so you know it will always be.
2) In the constructor, pass the class <T> as a parameter, so at runtime you will know what T. is (because it is erased)
Add a generic constraint, i.e. it would be better as it will handle it at compile time rather than throwing an exception at runtime.
class C <T extends Comparable>
You should check that your parameter T Comparable
.
public class C <T extends Comparable>
It's the same if you want the generic type to implement some kind of interface.
public class C <T implements <interface what you want> >
Or if you want it to be the superclass of another.
public class C <T super <class what you want> >
If you always want a type to T
implement Comparable
, you can enforce it as follows.
public class C<T extends Comparable<? super T>> {
public C() {
}
}
This is better than throwing an exception at runtime. It won't even compile if someone tries to write new C<some non-Comparable type>()
. Note that it Comparable
is a generic type, so it cannot be used without type parameters; it shouldn't be easy
public class C<T extends Comparable>
If a type T
doesn't always implement Comparable
, but you want a particular constructor to work only for types Comparable
, then the answer is that you can't do it with constructors, but you can do it with a static method.
public class C<T> {
public C() {
// Constructor that works with any T
}
public static <T extends Comparable<? super T>> C<T> getNew() {
C<T> c = new C<>();
// Do stuff that depends on T being Comparable
return c;
}
}