繁体   English   中英

课堂上未经检查的警告<Collection>

[英]unchecked warning on Class<Collection>

假设我具有以下方法,该方法可用于创建指定的给定类型的集合。

private static Collection<?> void create(Class<? extends Collection<?>> cls) {
    return cls.newInstance();
}

如果在运行时传递cls参数,那么这一切都很好:

List<String> list = new LinkedList<String>();
create(list.getClass());

但是,如何在没有未经检查的警告的情况下在代码中调用此方法? 假设我想执行以下操作:

create(LinkedList.class);

它将抱怨未定义create(Class),严格来说,这是正确的,因为List不是#capture的Collection,但是我如何使它工作?

非常感谢!

尼尔·古夫特(Neal Gafter) 在这里几乎完全讨论了这个问题。 解决方法是使用超级类型令牌 我相信,Guice就是用来维护通用类型信息的。

基本上,这是一个额外的类,可以用来表示一个类型,而不是使用Foo.class 您可以这样使用它:

TypeReference<LinkedList<String>> x = new TypeReference<LinkedList<String>>() {};
create(x);

请注意,您尝试使用原始类型LinkedList仍然会导致编译器抱怨,这是故意的-使用原始类型时,您基本上选择了类型安全。 但是,此方案允许您以其他方式难以表达的泛型类型。

我们这里有两种通用类型,一种是集合的子类型,一种是集合的元素类型。 以下代码可以工作:

private static <C extends Collection<E>, E>
C create(Class<C> cls) throws Exception
{
    return cls.newInstance();
}

使用示例。 没有警告。

    Class<LinkedList<String>> clazz = ...;
    LinkedList<String> result = create(clazz);

现在的问题变成我们如何获得clazz 您必须非常说服编译器:

    List<String> list = new LinkedList<String>();
    clazz = (Class<LinkedList<String>>)list.getClass();

    clazz = (Class<LinkedList<String>>)(Class<?>)LinkedList.class;

我们可以使用一种实用方法来简化类型转换:

public static <C extends Collection, E, T extends Collection<E>>
Class<T> type(Class<C> classC, Class<E> classE)
{
    return (Class<T>)classC;
}

//usage:
    clazz = type(LinkedList.class, String.class);
    result = create(clazz);

有趣的是递归的:

    Class<LinkedList<LinkedList<String>>> clazz2;
    LinkedList<LinkedList<String>> result2;

    clazz2 = type(LinkedList.class, clazz);
    result2 = create(clazz2);

但是在某个时候,我们必须停止这场愚蠢的比赛。 泛型打字应该帮助我们,而不是折磨我们。 当它变得太麻烦并且使我们的程序无法阅读时,请将其删除。 使用我们幸福生活多年的该死的原始类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM