Вы не можете объявить карту таким образом.По сути, в Java нет достаточно выразительной системы типов для этого.
Но, к счастью, язык предоставляет запасной штрих от использования системы типов в виде casts .По сути, приведение - это способ предоставления информации о типе, которой нет у компилятора;Однако на вас ложится обязанность убедиться, что он действительно является безопасным типом.
Во-первых, объявите карту с подстановочными типами:
private final Map<A<?>,B<?>> map;
Затем, помещайте на карту только пары ключ / значение, которые do соответствуют ограничению:
<T> void put (A<T> key, B<T> value) {
map.put(key, value);
}
И затем разыгрываете, когда вы снова получаете элемент:
@SuppressWarnings("unchecked") // Safe
<T> B<T> get(A<T> key) {
return (B<T>) map.get(key);
}
Дело в том, что вы можете знать больше о типах, чем компилятор.При условии, что вы позаботились о том, чтобы ставить только безопасные пары, их можно безопасно разыграть.(Также необходимо убедиться, что метод equals
учитывает тип, поэтому A<T>
не равно A<S>
, если S == T
).
Это в основном «безопасный для типа гетерогенный контейнер», как описано в Effective Java (пункт 33 в 3-м издании).
Мне интересно, есть ли более элегантный способ, который не требует от меня приведения каждого значения, которое я получаю?.
Во-первых, вы на самом деле не выполняете приведение в методе get
во время выполнения: вот что означает непроверенное приведение.
Для другого, дженерики вводят загружает приведений - в основном, дженерики - это просто способ избежать вставки приведений вручную.Поэтому, если бы была проблема с приведениями (например, производительность), вы бы уже наблюдали это во многих местах.
Перефразируя Кубрика: перестаньте беспокоиться и полюбите состав.