JLS(参数化类型)的 4.5 节中提到了以下符号:
S[F1:=T1,...,Fn:=Tn]
。
我不太明白这个符号的含义。
下一段提到过:
泛型类型具有类型参数 F1,...,Fn 以及相应的边界 B1,...,Bn。参数化类型的每个类型参数 Ti 的范围超过 所有类型是相应列表中列出的所有类型的子类型 边界。也就是说,对于 Bi 中的每个绑定类型 S,Ti 是 S[F1:=T1,...,Fn:=Tn] (§4.10).
上面这句话的意思很清楚了。
但是我不清楚为什么我们在
[F1:=T1,...,Fn:=Tn]
之后有
S
我觉得这看起来不对。
首先:如果没有括号部分,这句话是对前面的陈述的正确重述,并且都符合我对java语言的理解。
第二:符号错误。 §4.10 引用了子类型和超类型符号 <: and :>,但实际使用的是替换符号 := (实际上并未在版本 8 中定义为替换符号,而是在版本 7 中定义,并在文档的其他部分中用作替换)。
最后:JSL 的先前版本对于相同的表示法有一个更加荒谬的版本。
泛型类或接口声明 C(第 8.1.2 节,第 9.1.2 节),其中一个 或多个具有相应边界的类型参数 A1,...,An B1,...,Bn 定义一组参数化类型,每个可能的类型都有一个 类型参数部分的调用。
集合中的每个参数化类型都是 C 形式,其中 每个类型参数 Ti 的范围涵盖所有类型的子类型 相应绑定中列出的类型。也就是说,对于每个绑定类型 Bi、Ti 中的 Si 是 Si[F1:=T1,...,Fn:=Tn] 的子类型。
它具有相同的括号,但这次甚至没有提及括号中使用之前的 F 是什么。
在版本 6 和版本 7 之间重写本节时,看起来括号复制不正确。版本 6 有括号,但仅意味着每个类型参数都会发生边界检查。
这是我的想法。
符号
[F1:=T1,...,Fn:=Tn]
是用概念类型(或通配符)Fi
替换每个类型参数Ti, i=1,2,...n
。
泛型类可以被认为是带有
(n+1)
参数 f(F1,F2,...,Fn, S)
的函数,其中 Fi
- 是类型参数,S
属于以下有限集 {B1,B2,...,Bn}
。
如果我们替换 [F1:=T1,...,Fn:=Tn]
,我们会得到带有一个参数的函数:
g(s)=f(T1,T2,...,Tn,S)
。
考虑到
[F1:=T1,...,Fn:=Tn]
是用 Fi
替换 Ti, i=1,2,...,n
我们可以引入新的符号:
f(T1,T2,...,Tn,S)=h(S)[F1=T1,...,Fn=Tn]
。
函数
h(S)
应该是线性的:h(S)=S
最后我们有:
f(T1,T2,...,Tn,S)=S[F1=T1,...,Fn=Tn]
。
因此概念
S[F1=T1,...,Fn=Tn]
的意思是:以固定值Bi
获取上限Fi=Ti
之一。
§1.3 定义了该符号的含义:
Java 编程语言的类型系统有时依赖于替换的概念。符号 [F_1:=T1,...,Fn:=Tn] 表示用 Ti 代替 Fi,1 ≤ i ≤ n。
我们不要忘记,每个边界中的接口类型 S 本身都可以是泛型的。这就是为什么根据替换,生成的类型 S 可能会有所不同。
例如,
interface SomeInterface<X, Y> { }
class Gen<T, Z extends Number & SomeInterface<T, Z>> {}