【问题标题】:How to type-safe add element to list whose generic extends class and implements interface?如何类型安全地将元素添加到泛型扩展类并实现接口的列表中?
【发布时间】:2021-05-26 09:26:59
【问题描述】:

我正在寻找一种类型安全、经过检查的解决方案,以将元素添加到其泛型需要类和接口的列表中。该示例说明了我想做的事情 - 添加一个类型为 Cat 扩展 Animal 并实现 Quadruped 的对象到列表 List<T> ,其中 T extends Animal & Quadruped

class Example {
    public interface Quadruped { };
    public static class Animal { };
    public static class Cat extends Animal implements Quadruped { };

    public <T extends Animal & Quadruped> List<T> getQuadrupedAnimals(){
        List<T> result = new ArrayList<>();
        Cat cat = new Cat();
        result.add(cat); // compile error
        return result;
    }
}

当然,将cat 转换为B 会解决编译错误,但不会被选中。

有什么解决办法吗?如果没有,有谁知道编译器不允许这样做的原因吗?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    有谁知道编译器不允许这样做的原因吗?

    T 是一个特定 Animal and Quadraped,在getQuadrupedAnimals() 的调用站点选择。

    该方法的合法调用包括:

    List<Dog> listOfDogs = getQuadrupedAnimals();
    List<Hamster> listOfHamsters = getQuadrupedAnimals();
    

    因此您不能将Cat 放入该列表(也不能将DogHamster 放入该列表中),因为您放入的任何内容都可能无法转换为调用者想要的类型。 (不过,您可以将文字 null 放入列表中)。

    如果要返回包含Cats 的列表,解决方案是将返回类型声明为List&lt;Cat&gt;(或List&lt;? extends Cat&gt;,或List&lt;? super Cat&gt;)。


    只有在参数中使用交集类型时才会真正有用,例如

    public <T extends Animal & Quadruped> List<T> getQuadrupedAnimals(T animal){
      return List.of(animal);
    }
    

    public <T extends Animal & Quadruped> int countLegs(List<T> animals){
      return 4 * animals.size();
    }
    

    【讨论】:

      猜你喜欢
      • 2020-07-19
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-19
      相关资源
      最近更新 更多