带通配符的 Java 泛型

发布于 2024-07-26 20:04:26 字数 1321 浏览 7 评论 0原文

有任何方法可以解决这种情况(我已尝试尽可能简化该场景):

public class Test {

    public static void main(String[] args) {

        /*
         * HERE I would like to indicate that the CollectionGeneric can be of
         * something that extends Animal (but the constructor doesn't allow
         * wildcards)
         */
        CollectionGeneric<? extends Animal> animalsCollectionGeneric = new CollectionGeneric<Animal>();
        List<? extends Animal> animals = getAnimals();
        /* Why I cannt do that? */
        animalsCollectionGeneric.setBeans(animals);
    }

    private static List<? extends Animal> getAnimals() {
        return new ArrayList<Dog>();
    }
}

class CollectionGeneric<T> {
    private List<T> beans;

    public List<T> getBeans() {
        return (beans != null) ? beans : new ArrayList<T>();
    }

    public void setBeans(List<T> beans) {
        this.beans = beans;
    }
}

interface Animal {}

class Dog implements Animal{}

这种情况给了我下一个错误:

The method setBeans(List<capture#2-of ? extends Animal>) in the type    
CollectionGeneric<capture#2-of ? extends Animal> is not applicable for
the arguments (List<capture#3-of ? extends Animal>)*

我不确定是否有办法用泛型来做到这一点,

There is any way to fix this situation (I have try to simplyfy the scenario as much as i could):

public class Test {

    public static void main(String[] args) {

        /*
         * HERE I would like to indicate that the CollectionGeneric can be of
         * something that extends Animal (but the constructor doesn't allow
         * wildcards)
         */
        CollectionGeneric<? extends Animal> animalsCollectionGeneric = new CollectionGeneric<Animal>();
        List<? extends Animal> animals = getAnimals();
        /* Why I cannt do that? */
        animalsCollectionGeneric.setBeans(animals);
    }

    private static List<? extends Animal> getAnimals() {
        return new ArrayList<Dog>();
    }
}

class CollectionGeneric<T> {
    private List<T> beans;

    public List<T> getBeans() {
        return (beans != null) ? beans : new ArrayList<T>();
    }

    public void setBeans(List<T> beans) {
        this.beans = beans;
    }
}

interface Animal {}

class Dog implements Animal{}

this scenario is giving me the next error:

The method setBeans(List<capture#2-of ? extends Animal>) in the type    
CollectionGeneric<capture#2-of ? extends Animal> is not applicable for
the arguments (List<capture#3-of ? extends Animal>)*

I am not sure about if there is a way to do this with generics,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情独悲 2024-08-02 20:04:26

这意味着无法证明两个集合具有相同的类型界限:

    CollectionGeneric<? extends Animal> animalsCollectionGeneric = 
             new CollectionGeneric<Animal>(); 
    List<? extends Animal> animals = getAnimals()

第一个集合在运行时可能具有 CollectionGeneric,第二个集合可能具有 List代码>. 混合这些将意味着你失去类型安全(更不用说大屠杀)。

因此,您需要向编译器证明这两者是相关的,因此您的通用签名应该是:

public void setBeans(List<? extends T> beans) {}
public List<T> getBeans();

并用作:

List<? extends Animal> beans = getBeans();
GenericCollection<Animal> animals = new GenericCollection<Animal>();
animals.add(beans);

What this means is that the two collections can not be proved to have the same type bounds:

    CollectionGeneric<? extends Animal> animalsCollectionGeneric = 
             new CollectionGeneric<Animal>(); 
    List<? extends Animal> animals = getAnimals()

The first one might at runtime have CollectionGeneric<Tiger> and the second one List<Gnu>. Mixing those would mean you lose the type safety ( not to mention the carnage ).

Therefore you need to prove to the compiler that those two are related, so your generic signatures should be:

public void setBeans(List<? extends T> beans) {}
public List<T> getBeans();

and used as:

List<? extends Animal> beans = getBeans();
GenericCollection<Animal> animals = new GenericCollection<Animal>();
animals.add(beans);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文