Условия хранения 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" таким образом, который затем можно использовать для списков или карт, и гарантировать, что это будет одинаковым для нескольких шаблонов с тех пор.