Используя необработанный тип, вы не можете компилятор запретить вам добавлять на карту старый ключ и значение. Это может быть хорошо, если ваши ключи и значения будут Object
с, но это не очень распространено в моем опыте.
Используя явные ограничения типа, ваш код не будет компилироваться, если вы попытаетесь передать параметры неправильного типа. Например:
Map<String, String> genericMap = new HashMap<>();
genericMap.put(new Object(), new Object()); // compiler error.
Однако, если вы должны были написать:
Map rawMap = genericMap;
rawMap.put(new Object(), new Object()); // fine.
Так что теперь в основном все ставки выключены, как к тому, что содержится в этой карте. Если вы передаете genericMap
к отдаленному методу, который ожидается в Map<String, String>
и собираетесь потреблять значения из него, вы собираетесь получить отказ во время выполнения, вероятно, ClassCastException
:
import java.util.HashMap;
import java.util.Map;
class DontDoThis {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Map<String, String> genericMap = new HashMap<>();
Map rawMap = genericMap;
rawMap.put(new Object(), new Object());
useMap(genericMap);
}
private static void useMap(Map<String, String> map) {
for (String key : map.keySet()) {} // ClassCastException.
}
}
При использовании подстановочных границы, вы можете» т делать такие вещи, как положить новые значения в карту:
Map<?, ?> wildcardMap = genericMap;
genericMap.put("key1", "value1"); // fine.
wildcardMap.put("key", "value"); // compiler error.
Вы можете, однако, по-прежнему использовать значение из wildcardMap
; все, что вы можете знать о них является то, что значения являются подтипами Object
:
for (Map.Entry<?, ?> entry : wildcardMap.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
// Use key and value somehow.
}
Что касается вопроса о том, как она может быть поймана в тесте - вы не должны писать тесты для такого рода вещи - успешная компиляция - это ваш тест!
Вид покрытия, который обеспечит вам безопасность во время компиляции, значительно больше, с существенно меньшим количеством кода, чем любой тест, который вы могли бы практически надеяться написать.
«* Eclipse выдаст предупреждение для такого назначения, потому что это неконтролируемая, небезопасная операция» * Компилятор Java выдаст предупреждение типа raw, а не непроверенную/небезопасную операцию. – m0skit0