I need to create a parametric class where I have two constructors, the first has a comparator as an argument, the second hasn't any argument but I can use it only if the parameter implements comparable or throws an exception otherwise.
To be more clear I need to do something like this:
class Storage<T>{
private Comparator<? super T> comparator = null;
public Storage() {
//T sould implement comparable, but how I can check it?
}
public Storage(Comparator<? super T> t){
//T doesn't implement comparable but i can use comparator!
comparator = t
}
public static void main(String[] args) {
//Just a test
Comparator<prova> comp = (a, b) -> 1;
MinMaxStorage<Integer> uno = new MinMaxStorage<>();
//Should thow an exception
MinMaxStorage<NotComparable> due = new MinMaxStorage<>();
//Should be ok
MinMaxStorage<NotComparable> due = new MinMaxStorage<>(comp);
}
}
You can't constrain direct invocations of this no-arg constructor: it can be called for any T
within the bounds. Given that there is no bound, this means it can be invoked for incomparable T
.
Instead, make the no-arg constructor private, and make a generic static factory method:
private Storage() {}
// ...
public <T extends Comparable<? super T>> Storage<T> create() {
return new Storage<>();
}
Then, this:
MinMaxStorage<NotComparable> due = MinMaxStorage.create();
won't throw an exception, but even better: it will not compile.