我搜索了其他类似的问题,但我认为它们没有涵盖这个问题.我有以下代码,这会导致编译错误:
// Example 1 (not working)
public interface I<T extends Number> {
void method(Map<String, String> map, T value);
}
public abstract class A<T extends Number> implements I<T> {
@Override
public void method(Map<String, String> map, T value) {}
}
// Note that C doesn't know about the generic type
public class C extends A {
// Error: name clash: method(Map<String,String>,Number) in C and
// method(Map,Number) in A have the same erasure, yet neither overrides the other
@Override
public void method(Map<String, String> map, Number n) {}
}
我理解类型擦除,但当我"手动"输入擦除时,它可以工作,所以这段代码很好.
// Example 2 (working)
public interface I<T extends Number> {
void method(Map map, T value);
}
public abstract class A<T extends Number> implements I<T> {
@Override
public void method(Map map, T value) {}
}
public class C extends A {
// No error
@Override
public void method(Map map, Number n) {}
}
泛型T大概也不是问题,因为如果我删除Map参数,它就可以工作,所以这也没问题(而且无论如何,错误是关于Map而不是泛型类型,所以这并不奇怪):
// Example 3 (working)
public interface I<T extends Number> {
void method(T value);
}
public abstract class A<T extends Number> implements I<T> {
@Override
public void method(T value) {}
}
public class C extends A {
// No error
@Override
public void method(Number n) {}
}
但是删除type参数也可以修复它,所以我想问题也不是映射:
// Example 4 (working)
public interface I {
void method(Map<String, String> map);
}
public abstract class A implements I {
@Override
public void method(Map<String, String> map) {}
}
public class C extends A {
@Override
public void method(Map<String, String> map) {}
}
这是一个小例子,但它突然出现是因为我试图在不需要更改C的情况下将泛型类型T添加到接口中,而C是在我不受控制的代码中实现的,所以不能用C以不兼容的方式更改I或A,但我希望能够在进行升级的类中使用泛型来使用泛型.不过,我认为这会起作用,并且使用现有类型添加带有约束的泛型将是一种向后兼容的更改,在大多数情况下确实如此,因为遵循示例3中形式的方法工作得很好.
无论如何,我不确定这里的错误到底是什么,因为示例3工作,任何关于一般形式无效的理论似乎都是不正确的,但是因为示例2工作,它也感觉这与类型擦除无关,但也许是泛型和类型擦除之间的一些有趣的交互,我不知道.