了解捕获的转换

12 java generics

我试图了解捕获的转换如何适用于通配符类型.JLS中有一节解释说:

让我们G使用带有相应边界的n类型参数A1,...,An来命名泛型类型声明(第8.1.2节,第9.1.2节)U1,...,Un.

存在从参数化类型G<T1,...,Tn>(第4.5节)到参数化类型的捕获转换 G<S1,...,Sn>,其中,用于1 ? i ? n:

  • 如果Ti是表单的通配符类型参数(第4.5.1节)?,那么它Si是一个新的类型变量,其上限是Ui[A1:=S1,...,An:=Sn],其下限是null类型(第4.1节).

  • 如果Ti是表单的通配符类型参数? extends Bi,那么它Si是一个新的类型变量,其上限是glb(Bi, Ui[A1:=S1,...,An:=Sn]),其下限是null类型.

    glb(V1,...,Vm)被定义为V1 & ... & Vm.

    它是一个编译时间错误,如果,对任何两个类(未接口)ViVj,Vi不是的一个子类Vj,或反之亦然.

  • 如果Ti是表单的通配符类型参数? super Bi,那么它Si是一个新的类型变量,其上限是Ui[A1:=S1,...,An:=Sn],其下限是Bi.

  • 否则,Si = Ti.

我不清楚的是Ui[A1:=S1,...,An:=Sn].这是什么意思?我无法找到通过JLS搜索的定义.

And*_*own 5

第一的:定义替代。

\n

[A1:=S1,...,An:=Sn]是JLS 表示法的替换(\xc2\xa71.3),定义为:

\n
\n

该符号表示替换为[F1:=T1,...,Fn:=Tn]FiTi1 \xe2\x89\xa4 i \xe2\x89\xa4 n

\n
\n

语句:是将 的类型参数( 的)替换为的类型变量。(另见脚注\xe2\x80\xa0[A1:=S1,...,An:=Sn]GAi Si1 \xe2\x89\xa4 i \xe2\x89\xa4 n

\n

接下来:考虑为什么我们在第一种情况下可能需要替换。来自\xc2\xa75.1.10(突出显示添加到下一点):

\n
\n

让我们G命名一个泛型类型声明...以及带有相应边界的n类型参数A1,...,An U1,...,Un

\n
\n

那是:

\n
    \n
  • 边界具体对应于类型参数。U1,...,Un A1,...,An
  • \n
  • 未声明的推论:边界与类型变量不对应。U1,...,UnS1,...,Sn
  • \n
\n

放在一起:我现在正在陈述显而易见的事情,因为我确信您领先于我,但是......

\n

关于“是通配符类型参数......形式为”的规则Ti?

\n
\n

Si是一个新类型变量,其上限为Ui [A1:=S1,...,An:=Sn]

\n
\n
    \n
  • Si是一个新鲜类型变量
  • \n
  • 其上限为Ui
  • \n
  • 其中(这是隐含的位)
  • \n
  • 类型参数具体对应于A1,...,AnU1,...,Un
  • \n
  • 已被类型变量替换S1,...,Sn
  • \n
  • 使得对应类型变量U1,...,UnS1,...,Sn
  • \n
\n

长话短说

\n

即它只是意味着原始上限也是UiSi

\n

脚注

\n

\xe2\x80\xa0从 JLS 中回忆一下类型变量和类型参数不是同一件事是有帮助的(因此我们可以开始了解为什么需要替换):

\n
\n

类型变量是在类、接口、方法和构造函数主体中用作类型的非限定标识符。\n

\n

类型变量是通过泛型类、接口、方法或构造函数的类型参数的声明引入的。

\n
\n