Условия хранения Java по универсальному типу

Я читал "Эффективную Java" и решил попробовать применить кое-что из того, что я изучил. Я пытаюсь эффективно создать Multimap<?, Condition<?> > где подстановочный знак будет одинакового типа как для ключа, так и для значения, но это будут разные, разные типы.

Вот предмет из книги, на которую я смотрю: Пункт 29

Я не пытаюсь полностью повторить это. Я понимаю, что большая разница в том, что ключ не представляет значение непосредственно по ссылке. В моем случае ключ представляет общий тип значения.

Так я сделаю mmap.put(Class<Integer>, ConditionMapping<Integer>)когда я получаю get, у меня нет общего типа ConditionMapping, поэтому я получаю предупреждение о неконтролируемом приведении.

У меня есть метод get, который я хочу иметь подпись <T> List<Condition <T> >(Class<T> type)

Из-за стирания типа мой единственный вариант - убедиться, что условие.value относится к типу T, и создать новый список объектов?

Я мог бы просто проигнорировать предупреждение о неконтролируемых ролях, но я просто стараюсь этого не делать. Какие-либо предложения? Подсказки? Трюки?

4 ответа

Решение

Нет никакого способа выразить, что два подстановочных знака должны захватывать один и тот же тип. Посмотрите этот вопрос для аналогичной ситуации и ряда возможных решений.

Если вы сделаете ваш интерфейс расширенным Multimap<Void, Condition<?>> он позволяет вашему пользователю вызывать некоторые из методов, которые не зависят от безопасности типов (например, containsKey), но не добавляют записи (минуя прокси-методы с проверкой типа), если они не используют непроверенные приведения.

interface ConditionMapBase<T> extends Multimap<T, Condition<?>> {
}
interface ConditionMap extends ConditionMapBase<Void> {
    <T>boolean putCondition(T key, Condition<T> value);
    <T>Collection<Condition<T>> getConditions(T key);
}
class ConditionMapImpl
extends ForwardingMultimap<Void, Condition<?>>
implements ConditionMap {

    ConditionMapImpl() {
        delegate = HashMultimap.create();
    }
    @SuppressWarnings("unchecked")
    @Override
    protected Multimap<Void, Condition<?>> delegate() {
        return (Multimap<Void, Condition<?>>) (Multimap<?, ?>) delegate;
    }
    private final Multimap<Object, Condition<?>> delegate;
    @SuppressWarnings("unchecked")
    @Override
    public <T> Collection<Condition<T>> getConditions(T key) {
        return (Collection<Condition<T>>) (Collection<?>) ((ConditionMapBase<T>) this).get(key);
    }
    @SuppressWarnings("unchecked")
    @Override
    public <T> boolean putCondition(T key, Condition<T> value) {
        return ((ConditionMapBase<T>) this).put(key, value);
    }
}

Это может быть шагом в правильном направлении.

<Multimap<Class<?>, Condition<?>>

Вы можете создать MyClass, а затем передать ему свой собственный тип и заключить в нем Multimap. Невозможность шаблонов в Java часто может быть решена путем добавления другого слоя, так сказать, и создания шаблона класса, который вам действительно нужен, поскольку вы можете получить тип "T" таким образом, который затем можно использовать для списков или карт, и гарантировать, что это будет одинаковым для нескольких шаблонов с тех пор.

Другие вопросы по тегам