[英]Java Type Erasure Problem
我举了一个例子来证明我的问题:
Metrical.java
public interface Metrical<T>
{
double distance(T other);
}
Widget.java
public class Widget implements Metrical<Widget>
{
private final double value;
public Widget(double value) { this.value = value; }
public double getValue() { return value; }
public double distance(Widget other) { return Math.abs(getValue() - other.getValue()); }
}
Pair.java
public class Pair<T>
{
private final double value;
private final T object1, object2;
public Pair(T object1, T object2, double value)
{
this.object1 = object1;
this.object2 = object2;
this.value = value;
}
public T getObject1() { return object1; }
public T getObject2() { return object2; }
public double getValue() { return value; }
}
Algorithm.java
import java.util.Set;
public class Algorithm<T extends Metrical<T>>
{
public void compute(Set<T> objects)
{
}
public void compute(Set<Pair<T>> pairs)
{
}
}
因此,在Algorithm.java中 , Set <Pair <T >>被视为Set <T> ,因此我遇到类型擦除问题。 但是,有没有什么办法可以在不命名方法的情况下摆脱这样的事情? 算法的两种变体都是为了对T进行操作,但我需要允许不同的参数。 他们计算同样的事情,所以为了避免混淆,我宁愿不以不同的名字命名。 有没有办法容纳这个?
不,没有。
你必须记住,有人可以用一个香草集调用你的方法,在这种情况下会调用哪一个?
这就是为什么你不能这样做的原因。 就像你做不到:
interface A {
void blah(Set set);
void blah(Set<T> set);
}
同样的问题。
类型信息在运行时不可用(即类型擦除)。
对不起,坏消息是你不能这样做:
public class Algorithm<T extends Metrical<T>> {
public void compute(Set<T> objects) {
}
public void compute(Set<Pair<T>> pairs) {
}
}
由于擦除,两者都将擦除相同的签名。 没有办法解决其中一种方法的重命名问题。
遗憾的是,这是Java Generics倒闭的主要领域......没有好的解决方案。
我通常使用接口作为Set<Pair<T>>
创建一个新类,但是包装Set<Pair<T>>
(不扩展它,这会导致同样的问题)。
我写了一篇关于类型擦除的文章,这可能是你感兴趣的。 它提供了常见的广为人知的解决方案,也是解决问题的棘手方法。 我不知道它是否适合你。 无论如何,它包含一些在某些情况下可能有用的技术。
另请参阅: 使用TypeTokens检索通用参数
我希望它有所帮助。
使用public class Widget<K, P> implements Metrical<K extends Widget<P>>
。
public double distance(Widget other) {}
成为public double distance(Widget<P> other) {}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.