java:如何修复未选中的强制转换警告

时间:2010-12-08 13:35:41

标签: java generics casting

我有以下代码:

private HashMap<Class<?>, HashMap<Entity, ? extends Component>> m_componentStores;

public <T extends Component> T getComponent(Entity e, Class<T> exampleClass)
{
    HashMap<Entity, ? extends Component> store = m_componentStores.get(exampleClass);

    T result = (T)store.get(e);

    if (result == null)
    {
        throw new IllegalArgumentException( "GET FAIL: "+e+" does not possess Component of class\nmissing: "+exampleClass );
    }

    return result;
}

当我编译时,它显示T result = (T)store.get(e)有未经检查的强制转换。

Type safety: Unchecked cast from capture#2-of ? extends Component to T

我错过了什么来防止出现此警告?

3 个答案:

答案 0 :(得分:37)

Class.cast就是你想要的。好吧,你可能会考虑不使用反射。

更改行:

T result = (T)store.get(e);

为:

T result = exampleClass.cast(store.get(e));

答案 1 :(得分:16)

在Cast语句上方写@SuppressWarnings("unchecked")

@SuppressWarnings("unchecked")
T result = (T)store.get(e);

并添加一个解释性声明,说明为什么忽略警告是安全的。

答案 2 :(得分:4)

泛型中的

extends并不是真的那样。 T!= ? extends Component即使是T extends Component。你所拥有的实际上是wildcard capture,它有不同的目的。

是的,您的解决方案不是类型安全的 - 以下两个?标记之间没有关系:

    private HashMap<Class<?>, HashMap<Entity, ? extends Component>> m_componentStores;

因此,使用其他类(甚至不是Component的子类)作为键,将Component的某个子类的实例放在此结构中是合法的。

请记住,泛型类型仅在编译时解析,因此在运行时 m_componentStores无法知道您拥有的值的确切类型在那里,除了它extends Component

因此,您从store.get(e)获得的类型是...... Component

    Component result = store.get(e);

Component强制转换为T时,编译器会发出警告,因为无法静态检查强制转换。但是,如果您确定数据结构的语义,则可以简单地禁止警告。

    @SuppressWarnings("unchecked")
    T resultT = (T)result;

PS: 您不需要通配符捕获,以下内容在您的情况下将完全相同:

    private HashMap<Class<?>, HashMap<Entity, Component>> m_componentStores;