Ничего себе; Думаю, я разобрался с ответом на свой вопрос. Я просто не уверен, что оно того стоит! :)
Проблема в том, что актерский состав не проверен. Итак, вы должны проверить это сами. Невозможно просто проверить параметризованный тип с помощью instanceof, поскольку информация о параметризованном типе недоступна во время выполнения, поскольку она была стерта во время компиляции.
Но вы можете выполнить проверку каждого элемента в хэше, используя instanceof, и при этом вы можете создать новый хеш, который является типобезопасным. И вы не будете провоцировать никаких предупреждений.
Благодаря mmyers и Esko Luontola я параметризовал код, который я изначально написал здесь, так что он может быть помещен в служебный класс где-нибудь и использован для любого параметризованного HashMap. Если вы хотите лучше понять его и не очень знакомы с дженериками, я рекомендую просмотреть историю редактирования этого ответа.
public static <K, V> HashMap<K, V> castHash(HashMap input,
Class<K> keyClass,
Class<V> valueClass) {
HashMap<K, V> output = new HashMap<K, V>();
if (input == null)
return output;
for (Object key: input.keySet().toArray()) {
if ((key == null) || (keyClass.isAssignableFrom(key.getClass()))) {
Object value = input.get(key);
if ((value == null) || (valueClass.isAssignableFrom(value.getClass()))) {
K k = keyClass.cast(key);
V v = valueClass.cast(value);
output.put(k, v);
} else {
throw new AssertionError(
"Cannot cast to HashMap<"+ keyClass.getSimpleName()
+", "+ valueClass.getSimpleName() +">"
+", value "+ value +" is not a "+ valueClass.getSimpleName()
);
}
} else {
throw new AssertionError(
"Cannot cast to HashMap<"+ keyClass.getSimpleName()
+", "+ valueClass.getSimpleName() +">"
+", key "+ key +" is not a " + keyClass.getSimpleName()
);
}
}
return output;
}
Это много работы, возможно, за очень маленькую награду ... Я не уверен, буду ли я ее использовать или нет. Буду признателен за любые комментарии относительно того, думают ли люди, что это того стоит или нет. Кроме того, я был бы признателен за предложения по улучшению: есть ли что-то лучшее, что я могу сделать, кроме как бросить AssertionErrors? Есть ли что-то лучшее, что я мог бы бросить? Должен ли я сделать это проверенным исключением?