通配符类型,类型擦除和运行时签名:<t extends =“”a =“”&=“”b =“”> A和B是否继承了共同的祖先?</t>

时间:2014-03-15 15:52:05

标签: java generics type-erasure method-signature

(编辑:评论后修复)

让我们采用一个类或接口A和一个接口B,其中两个都继承了一个共同的祖先X(假设X不是Object)。让我们有一个签名为:

的方法
<T extends A & B> void foo(final T arg)

foo在运行时的签名是什么?是void foo(X)还是void foo(Object),JVM是否在运行时转换为X

1 个答案:

答案 0 :(得分:4)

类型参数的擦除始终是其最左边界的擦除,并不重要继承层次结构中的其他类(JLS §4.6)。因此,该方法被删除为:

void foo(final A)

当然,如评论中所述,如果AB都是类,则该代码将无法编译。类型参数边界不能将多个类作为边界,而只能使用单个类,后跟任意数量的接口。

有关类型变量声明的语法,请参阅JLS §4.4

TypeParameter:
    TypeVariable TypeBoundopt

TypeBound:
    extends TypeVariable
    extends ClassOrInterfaceType AdditionalBoundListopt

AdditionalBoundList:
    AdditionalBound AdditionalBoundList
    AdditionalBound

AdditionalBound:
    & InterfaceType

任何 AdditionalBound 应始终为 InterfaceType

  

JVM在运行时转换为X?

是的,编译器将添加适当的强制转换,以便代码按预期工作。