?,java,generics"/>

首页 > 解决方案 > 如何将元素添加到列表中?

问题描述

我在有效使用泛型时遇到了麻烦。大多数时候,当我遇到下面描述的问题时,我最终会找到另一种方法来完成我需要的事情,但这让我觉得我对 Java 中泛型的使用缺乏一些了解。

如果我想创建一个返回列表的方法,其中 T 扩展了任何内容,我会收到一个编译器错误,说我添加到列表中的任何内容都不能转换为 T。

请参阅下面的代码示例:

public interface I1 {
}

public interface I2 {
}

public class ValidType implements I1, I2 {
}

public class OtherValidType extends ValidType {
}

public class Foo {
    private static <T extends I1 & I2> List<T> getList() {
        List<T> list = new ArrayList<>();
        list.add(new ValidType());
        list.add(new OtherValidType());
        return list;
    }
}

编译器甚至不会让我做一些更简单的事情,例如:

public class Foo {
    private static <T extends ValidType> List<T> getList() {
        List<T> list = new ArrayList<>();
        list.add(new ValidType());
        return list;
    }
}

我知道在第二个示例中我可以只做一个 List 并且继承该类型的类将被接受,这只是为了试图了解我对泛型的理解哪里出错了。

例如,以上所有都会产生编译错误“List 中的 add(T) 不能应用于 (ValidType)”。

我在哪里误解了泛型作为返回类型/类型参数的用法?

标签: javagenerics

解决方案


你怎么知道在这两个例子中都是orT的超类?ValidTypeOtherValidType

T可能是一些完全不同的类,也恰好实现了接口I1and I2,在这种情况下,您不能将ValidTypeand的实例OtherValidType放入其中。

对于您的第二个示例,请尝试:

List<OtherValidType> list = Foo.getList();

应该清楚的TOtherValidType,但是您试图在其中插入 a ValidType,但ValidType不是OtherValidType(它是超类)的子类。

在某些情况下,您可以使用该构造,例如:

private static <T extends I1 & I2> List<T> getList(T a, T b) {
    List<T> list = new ArrayList<>();
    list.add(a);
    list.add(b);
    return list;
}

但是如果你不知道什么是类型T,你就永远无法知道具体的已知类是否ValidType可以OtherValidType分配给它。


推荐阅读