这里为什么List<Subtype>可以赋值给List<Supertype>?

问题描述 投票:0回答:1

我知道 Java 通常是不变的,因为它不想处理协变/逆变问题。

所以总的来说,

List<Parent> a = new ArrayList<Child>();

需要通过

(List)
进行类似类型擦除的转换才能工作。

但是,

List<Parent> p = Collections.singletonList(<Child>);

按原样工作,无需演员,尽管声称通过

文档
返回List<Child>

我做了一些实验,发现这是一般回报的属性,而不是特定于

Collections.singletonList

这里有几种可能性:

  • 它根据分配的内容推断返回类型
    • 例如,它可以假装
      <Child>
      参数是
      (<Parent>) <Child>
      ,并进行隐式转换
    • 一个很好的观点是类似
      Vector<String> s = new Vector<>();
      ,在推理方面至少有点像这样
  • 它实际上只是返回
    List
    ,类型被删除,所以
    List<T>
    是一个用词不当
    • 这对我来说很有意义,但奇怪的是,这是编译器的例外情况,而不是我作为示例给出的第一个作业

这里到底发生了什么,为什么在这种情况下,函数返回泛型时可以,但一般赋值时不行?

更进一步,Java 是如何实现和特殊情况的?

java generics language-design
1个回答
0
投票

您误解了 javadoc。

singletonList
返回的名义类型:

List<Parent> p = Collections.singletonList(<Child>);

确实是

List<Parent>
。 javadoc 应该被理解为该方法的参数是
T
的实例或
T
的子类。
Child
Parent
的子类。

基本上,类型推断已经找出了

T
的类型,它满足上下文的所有类型约束......并使用了它。

© www.soinside.com 2019 - 2024. All rights reserved.