我有一个X
类,它具有以下方法:
public <T> List<T> g(List<T> l) {…}
我还有一个类Y
,它扩展了类X
并具有以下方法:
public <T> List<T> g(List<List<T>> l) {…}
据我了解,在类型擦除过程之后,它们都具有相同的原始类型。为什么Java不会将Y::g
视为X::g
的替代方法,并且无法编译代码?如果在g
中有ArrayList
而不是List
,怎么办?
答案 0 :(得分:1)
根据JLS,Y.g
会覆盖X.g
,尤其是在Y.g
是X.g
的子签名的情况下。
Y.g
仅是X.g
的{{3}},
Y.g
与X.g
具有相同的签名,即:public <T> List<T> g(List<T> l);
或者,Y.g
的签名与删除X.g
的签名相同:
因此,在这种情况下,Y.g
可能是public List g(List l)
。
根据您的描述,这两个条件都不成立,因此是错误的。
答案 1 :(得分:0)
我相信您误解了类型擦除。 Java中泛型的要点是允许在编译过程中进行更严格的类型检查,这仍然允许在运行时共享代码。为此,编译器会在编译过程中“擦除”该类型。当您在运行时使用反射检查类型时,这一点很重要。
因此,在您的情况下,编译器正确区分了两种不同的类型。在运行时对它们进行不同处理的事实对其签名没有影响。
有关该主题的介绍,请参见https://docs.oracle.com/javase/tutorial/java/generics/erasure.html;有关正式说明,请参见https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.6。