Подтвердить что ты не робот

Java: Как исправить предупреждение о немедленном нажатии

У меня есть следующий код:

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

Что мне не хватает, чтобы предотвратить появление этого предупреждения?

4b9b3361

Ответ 1

Class.cast - это то, что вы хотите. Ну, вы можете не использовать отражение.

Измените строку:

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

в

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

Ответ 2

Напишите @SuppressWarnings("unchecked") над выражением Cast:

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

И добавьте пояснительное выражение о том, почему безопасно игнорировать предупреждение.

Ответ 3

extends в дженериках на самом деле не работает. T!= ? extends Component, хотя T extends Component. То, что у вас есть на самом деле подстановочный знак, имеет другую цель.

И да, ваше решение не является безопасным по типу - между двумя метками ? нет связи:

    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;