【问题标题】:Java covarianceJava协方差
【发布时间】:2009-07-26 11:12:02
【问题描述】:

我很难弄清楚这一点。假设我有以下代码:

class Animal { }
class Mammal extends Animal { }
class Giraffe extends Mammal { }
...
public static List<? extends Mammal> getMammals() { return ...; }
...

public static void main(String[] args) {
    List<Mammal> mammals = getMammals(); // compilation error
}

为什么赋值会导致编译错误?错误类似于:

Type mismatch: cannot convert from List<capture#4-of ? extends Mammal> to List<Mammal>

根据我对协方差的理解,getMammals() 方法返回一个list,它总是包含Mammal 对象,所以它应该是可赋值的。我错过了什么?

【问题讨论】:

    标签: java covariance


    【解决方案1】:

    因为getMammals 可以返回List&lt;Giraffe&gt;,如果它可以转换为List&lt;Mammal&gt;,那么您就可以向它添加Zebra。您不能将Zebra 添加到Giraffe 的列表中,可以吗?

    class Zebra extends Mammal { }
    
    List<Giraffe> giraffes = new List<Giraffe>();
    
    List<Mammal> mammals = giraffes; // not allowed
    
    mammals.add(new Zebra()); // would add a Zebra to a list of Giraffes
    

    【讨论】:

      【解决方案2】:

      好吧,不幸的是,它不能那样工作。

      当您声明 getMammals() 返回 List&lt;? extends Mammal&gt; 时,这意味着它可以返回 List&lt;Mammal&gt;List&lt;Giraffe&gt; 但不能返回 List&lt;Animal&gt;

      你的 main() 应该是这样的:

      public static void main(String[] args) {
          List<? extends Mammal> mammals = getMammals();
          Mammal mammal = mammals.get(0);
      }
      

      编辑:关于协方差,这就是通常的意思:

      class Animal {
          public Animal getAnimal() {return this;}
      }
      
      class Mammal extends Animal {
          public Mammal getAnimal() {return this;}
      }
      
      class Giraffe extends Mammal {
          public Giraffe getAnimal() {return this;}
      }
      

      如您所见,它允许在覆盖方法时重载返回类型的方法。

      【讨论】:

      • + 1,但你能解释一下“List or List but not List”是什么意思吗?! :p
      • 重新格式化以删除令人困惑的“列表或列表但不是列表”:-)
      • 泛型被视为 html,已转义
      • 我不明白这个答案 - OP 不想将其视为 List&lt;Animal&gt;
      猜你喜欢
      • 2011-02-09
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      相关资源
      最近更新 更多