通用方法触发类型安全错误 - 为什么?

Dun*_*nes 7 java generics

在讨论这个问题的解决方案时,我想出了以下代码,它有一些编译器警告.一个警告是:

Type safety: The expression of type Test.EntityCollection needs unchecked conversion to conform to Test.EntityCollection<Test.Entity>

我不完全理解为什么出现这个警告.通过传入一个Class<M>类型并声明方法返回EntityCollection<M>,为什么我没有做足以说服(Java 7)编译器返回正确的类型?

static class Entity {
}

static class EntityCollection<E extends Entity> {

    private EntityCollection(HashMap<?, E> map) {
    }

    public static <T extends HashMap<?, M>, M extends Entity> EntityCollection<M> getInstance(
            Class<T> mapType, Class<M> entityType)
            throws ReflectiveOperationException {

        T map = mapType.getConstructor().newInstance();
        return new EntityCollection<M>(map);
    }
}

public static void main(String[] args) throws Exception {
    // both compiler warnings are on the line below:
    EntityCollection<Entity> collection = EntityCollection.getInstance(
            LinkedHashMap.class, Entity.class);
}
Run Code Online (Sandbox Code Playgroud)

如果任何人都可以改进代码以完全避免警告,则可获得奖励积分.我已经盯着它看了一段时间,并没有想到任何减少警告的方法.

Ada*_*old 3

问题是这getInstance是一个泛型方法,但您没有向它传递泛型类型参数。您可以通过像这样传递它们来绕过它:

    public static void main(String[] args) throws Exception {
        EntityCollection<Entity> collection = EntityCollection.<LinkedHashMap, Entity>getInstance(
                LinkedHashMap.class, Entity.class);
    }
Run Code Online (Sandbox Code Playgroud)

您仍然需要处理 rawtypes 警告,因为它LinkedHashMap是泛型类型。这在您的情况下是有问题的,因为密钥类型中有通配符。

您在这里面临几个问题:

你不能像这样传递参数化的类对象:LinkedHashMap<Object, Entity>.class所以你几乎陷入了原始类型警告。