开发者

java: How to fix the Unchecked cast warning

I've got the following code:

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( "G开发者_JS百科ET FAIL: "+e+" does not possess Component of class\nmissing: "+exampleClass );
    }

    return result;
}

When I compile, it shows that T result = (T)store.get(e) has an unchecked cast.

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

What am I missing to prevent this warning from appearing?


Class.cast is what you want. Well, you might consider not using reflection.

Change the line:

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

to:

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


Write @SuppressWarnings("unchecked") above the Cast statement:

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

And add a explanatory statement why it is safe to ignore the warning.


extends in generics doesn't really work that way. T != ? extends Component even though T extends Component. What you have is in fact a wildcard capture, it has a different purpose.

And yes your solution is not type-safe - there is no relation between the two ? marks in:

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

So it becomes legal to put an instance of some subclass of Component in this structure using some other class (not even a subclass of Component) as the key.

Remember that generic types are resolved at compile time only, so at run time m_componentStores has no way of knowing what exact type of the value you have in there, other than that it extends Component.

So the type you get from store.get(e) is ... Component:

    Component result = store.get(e);

When you cast Component to T, the compiler issues a warning because the cast cannot be checked statically. But if you're sure of the semantics of your data structure, you can simply suppress the warning.

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

PS: You don't need a wildcard capture, the following will work exactly the same in your case:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜