假设我有一个通用的class Generic<A extends BaseType>.
就Java语言规范而言,在以下两种类型声明之间是否存在显着差异?
Generic<?>
Generic<? extends BaseType>
Run Code Online (Sandbox Code Playgroud)
嵌套通配符怎么样?
List<Generic<?>>
List<Generic<? extends BaseType>>
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,我认为这些是等价的.Generic指定type参数A具有BaseType上限.
因此,BaseType无论是否明确指定,通配符都应始终"自动"或"隐式"限制.
下面,我尝试调和我的直觉与JLS.
我找不到有关"隐式"边界的信息,所以我从查看子类型规则开始.
阅读有关子类型$ 4.10.2的JLS部分,它说:
给定泛型类型声明
C<F1,...,Fn>(n> 0),参数化类型的直接超类型C<T1,...,Tn>(其中Ti(1≤i≤n)是一个类型)是以下所有:
D<U1 ?,...,Uk ?>,其中D<U1,...,Uk>泛型类型是泛型类型的直接超类型C<T1,...,Tn>,θ是替换[F1:= T1,...,Fn:= Tn].
C<S1,...,Sn>,其中Si含有Ti(1≤i≤n)(§4.5.1).
(强调我的)
据我所知,"通配符"在JLS中不被视为"类型".所以这不适用于前两个,但它适用于这两个List例子.
相反,这应该适用:
给定泛型类型声明
C<F1,...,Fn>(n> 0),参数化类型的直接超类型(C<R1,...,Rn>其中Ri( 1≤i≤n)中的至少一个是通配符类型参数)是参数化类型的直接超类型C<X1,...,Xn>,这是结果将捕获转换应用于C<R1,...,Rn>(§5.1.10).
(强调我的)
将捕获转换$ 5.1.10应用于Generic<?>和Generic<? …
Java 14 带来了记录,这是许多函数式语言中的一个很好的补充:
爪哇:
public record Vehicle(String brand, String licensePlate) {}
Run Code Online (Sandbox Code Playgroud)
毫升:
type Vehicle =
{
Brand : string
LicensePlate : string
}
Run Code Online (Sandbox Code Playgroud)
在 ML 语言中,可以通过创建一个更改了一些值的副本来“更新”记录:
let u =
{
Brand = "Subaru"
LicensePlate = "ABC-DEFG"
}
let v =
{
u with
LicensePlate = "LMN-OPQR"
}
// Same as:
let v =
{
Brand = u.Brand
LicensePlate = "LMN-OPQR"
}
Run Code Online (Sandbox Code Playgroud)
这在 Java 14 中可能吗?