I\'ve made an example to demonstrate my problem:
Metrical.java
public interface Metrical
{
double distance(T other);
}
Sorry, the bad news is that you cannot do this:
public class Algorithm<T extends Metrical<T>> {
public void compute(Set<T> objects) {
}
public void compute(Set<Pair<T>> pairs) {
}
}
Due to erasure, both will erase to the same signature. There is no way around this short of renaming one of the methods.
Use public class Widget<K, P> implements Metrical<K extends Widget<P>>
.
public double distance(Widget other) {}
becomes public double distance(Widget<P> other) {}
Sadly, this is the major area where Java Generics falls down... there is just no good solution.
I've generally resorted to making a new class, with the interface as Set<Pair<T>>
, but that wraps Set<Pair<T>>
(without extending it, which would cause the same problem).
No there isn't.
You have to remember that someone could call your method with just a vanilla Set, in which case which one would be called?
That's why you can't do it. Just like you can't do:
interface A {
void blah(Set set);
void blah(Set<T> set);
}
Same problem.
The type information isn't available at runtime (ie type erasure).
I've written an article about type erasure which can be of your interest. It gives the common widely known solution and also a tricky way to circumvent the problem. I don't know if it will be relevant for you. Anyway, it contains some techniques which may be useful under certain circumstances.
See also: Using TypeTokens to retrieve generic parameters
I hope it helps.