java怎么定义list t_关于泛型:Java规范在哪里说List< T>

假设类B继承自类A。以下是合法Java:

List x;

List super B> y = x;

就规范而言,这意味着List转让给List super B>。但是,我很难找到规范中说明这是合法的部分。特别是,我认为我们应该有亚型关系

List  <: super b>

但是Java 8规范的第4.10节定义了子类型关系作为直接超关系EDCOX1〔4〕的传递闭包,并且它定义了直接超关系,它是用一个有限函数来计算EDOCX1×5的一组超类型。在输入List上没有可以生成List super B>的有界函数,因为可能有任意数量的B继承自A,所以规范的子类型定义似乎对超级通配符是分解的。关于"类和接口类型之间的子类型"的第4.10.2节确实提到了通配符,但它只处理通配符出现在潜在子类型中的另一个方向(该方向适合于计算的直接父类型机制)。

问题:规范的哪一部分说明上述代码是合法的?

编译器代码的动机是,所以不足以理解为什么它是直观合法的,或者想出一个处理它的算法。由于Java中的泛型子类型问题是不可判定的,所以我希望处理与SPEC完全相同的情况,因此需要处理该情况的规范的一部分。

定义"子类型关系"?仿制药是不可复制的,所以我看不出你的观点。

不幸的是,我能做的最好的就是说,子类型关系在规范的第4.10节中定义:()第一个原则定义在这里没有帮助,因为它不本地化规范的哪个部分说我的特定通配符assignsto是有效的。我看不到规范的子类型关系处理它,但是我也看不到规范的assignsto关系如何处理它,所以我丢失了。

为了澄清,我所说的子类型的原因是,assignsto是通过扩大引用转换来定义的,而引用转换是通过子类型来定义的。然而,assignsto也被定义为一堆其他关系,因此相关的位可能与子类型无关。

List super B>由&sect;4.10.2定义为List的父类型。类和接口类型之间的子类型:

The direct supertypes of the parameterized type C1,...,Tn>, where Ti

(1 ≤ i ≤ n) is a type, are all of the following:

D1 θ,...,Uk θ>, where D1,...,Uk> is a direct supertype of C1,...,Tn> and θ is the substitution [F1:=T1,...,Fn:=Tn].

C1,...,Sn>, where Si contains Ti (1 ≤ i ≤ n) (§4.5.1).

让C1,...,Tn> = List和C1,...,Sn> = List super B>。根据第二颗子弹,如果? super B含有A,List super B>是List的超类型。

包含关系在&sect;4.5.1中定义。类型参数和通配符:

A type argument T1 is said to contain another type argument T2, written T2 <= T1, if the set of types denoted by T2 is provably a subset of the set of types denoted by T1 under the reflexive and transitive closure of the following rules (where denotes subtyping (§4.10)):

? extends T <= ? extends S if T

? super T <= ? super S if S

T <= T

T <= ? extends T

T <= ? super T

通过第二颗子弹,我们可以看到? super B含有? super A。最后一颗子弹,我们看到? super A含有A。因此,我们知道? super B包含A。

我做了这个社区维基,因为我不确定我是否所有的细节都正确。语言律师,请纠正我的任何错误。

"我不确定所有的细节都是正确的。"你做到了。

正如我在问题中提到的,4.10.2说要将捕获转换应用于子类型的对象,以找到它的直接父类型。但是,在这种情况下,子类型是List,因此没有要应用的捕获转换。因此,在我的案例中,我还不理解该部分是如何工作的。

啊,明白了。我错过了关键的一点。谢谢!

@geoffreyirving事实上,我认为你是对的,? super A不会在分配上下文中被捕获,但这并不重要。4.10.2和4.5.1的摘录表明,List super A>是List的直接超型。

太好了,上次的编辑删除了我误入歧途的部分。一切都好!

将列表分配给什么?超级B>实际上是什么意思?

考虑以下程序:

public class Generics {

static class Quux { }

static class Foo extends Quux { }

static class Bar extends Foo { }

public static void main(String... args) {

List fooList = new ArrayList<>();

// This is legal Java

List super Bar> superBarList = fooList;

// So is this

List super Foo> superFooList = fooList;

// However, this is *not* legal Java

superBarList.add(new Quux());

// Neither is this

superFooList.add(new Quux());

// Or this:

superFooList.add(new Object());

// But this is fine

superFooList.add(new Foo());

}

}

为什么会这样?首先,我们来谈谈捷豹路虎的说法

根据JLS,?4.5.1:

A type argument T1 is said to contain another type argument T2, written T2 <= T1, if the set of types denoted by T2 is provably a subset of the set of types denoted by T1 under the reflexive and transitive closure of the following rules (where ? super T <= ? super S if S T <= ? super T

因此,t<=?super s如果s…但这意味着什么?

如果我不能添加一个new Quux(),或者一个new Object()?List super Foo>意味着这个列表只包含对Foo是严格超类型的元素,但我不知道是哪种类型。换句话说,我可以声明列表是这样的一个类型,但是我不能向它添加元素,我不能100%地确定它是? super Foo类型。Quux可以是那种类型,但也可能不是那种类型。

因此,将List指定为List super Bar>不允许堆污染,最终也不是问题。

进一步阅读:Angelikalanger一般性解释的相关章节

这是一个很好的解释,我希望我的问题是关于直觉的理解或者安全的语义证明。两个都会容易得多!:)不幸的是,我陷入了编译器内部,特别需要在规范中为这种情况定义assignsto或subtype的位置。您完全正确地认为它应该与类型参数上的包含关系相关,但不幸的是,我不知道如何处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值