Reputation: 176
I am trying to write a custom comparator method to compare different things in my custom class Customer and when I compile I get incompatible types: T cannot be converted to Customer
. DataChecker.compare() is run from a generic method but I know that whenever it is run T will be a type that is defined in the overloaded DataChecker.compare() method. Below is my code:
public int compare(Customer cust1, Customer cust2, String sortBy){ //Comparator interface for customers
if (sortBy == "ID"){
if (cust1.getID() < cust2.getID()){
return -1;
} else if (cust1.getID() == cust2.getID()){
return 0;
} else {
return 1;
}
}
throw new IllegalArgumentException("Not a valid compare for Customer: " + sortBy);
}
The method is called here (left and right are T[ ] but when this is run T will be one of the types - e.g. Customer - that is defined in DataChecker.compare()):
if (DataChecker.compare(left[i], right[j], sortBy) <= 0){
input[k++] = left[i++];
} else {
input[k++] = right[j++];
}
Thanks in advance
Upvotes: 1
Views: 1293
Reputation: 102842
T will be a type that is defined in the overloaded DataChecker.compare() method.
That is almost entirely useless. In java, overloads are completely different methods that have absolutely no relationship whatsoever; code is interpreted at compile (write) time to one of the overloads, and that particular method is then hardcoded in your class file. At runtime, override is applied dynamically (java is fully dynamically dispatched), but the 'full name' of each method includes the complete type it is, the name, and the types of each parameter, and the return type.
In other words, it is not possible to tell the compiler: Just figure it out; call the right compare
method, and I guarantee you it will be there. I guess, if not, throw a ClassCastException or something.
If you think about it for a while, this starts to make some sense. String
is a subtype of Object
, but also of CharSequence
, and also of Serializable
. Imagine you had compare(Serializable a, Serializable b)
as well as compare(CharSequence a, CharSequence b)
. Which one should be called?
The only solution, then, is to either have no overloads, or to create a single method that is the entrypoint for this dynamic process, which does its own, handrolled dynamic dispatch, based on e.g. a Map<Class<?>, BiPredicate<?>>
or a bunch of instanceof
checks.
Upvotes: 5