List <List <T >>和List <T>是否具有相同的原始类型?

时间:2019-09-15 22:59:11

标签: java type-erasure raw-types

我有一个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,怎么办?

2 个答案:

答案 0 :(得分:1)

根据JLSY.g会覆盖X.g,尤其是在Y.gX.g的子签名的情况下。

Y.g仅是X.g的{​​{3}},

  • Y.gX.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