/ / Чи достатньо загортання "Непоміченої передачі з об'єкта на карту <String, Object>" у спробу / catch (ClassCastException), щоб уникнути проблем із запуском? - java, generics, кастинг, неперевірений

Обертається "Неочікуване відтворення з Object в Map <String, Object>" у спробі / злову (ClassCastException) достатньо, щоб уникнути проблем з роботою часу? - java, генерики, кастинг, неперевірені

Я пишу рекурсивний перетворювач для Map<String, Object> (мається на увазі Object частина також може бути Map<String, Object>, і так далі...

Фрагмент коду:

if(value instanceof Map) {
try {
return convert((Map<String, Object>)value);
} catch (ClassCastException ccex) {
ccex.printStackTrace();
return null;
}
}

все ще є попередження (Map<String, Object>)value:

Type safety: Unchecked cast from Object to Map<String,Object>

Поки я можу це помітити @SuppressWarnings("unchecked"), що мені цікаво:


Це catch (ClassCastException ccex) блокуйте вище, щоб уникнути будь-яких проблем із цим небезпечним актором?

Відповіді:

3 для відповіді № 1

Це catch (ClassCastException ccex) блокуйте вище, щоб уникнути будь-яких проблем із цим небезпечним актором?

Ні, точно оскільки це не перевірено. Він перевірить, що це a Map, але це "все на рівні JVM, завдяки тип стирання. Він може містити нестрокові ключі, і цей актер не зможе його виявити.

Розглянемо цей приклад:

import java.util.*;

class Test {
public static void main(String[] args) throws Exception {
Map raw = new HashMap();
raw.put(new Object(), 10);

// This cast won"t fail
Map<String, Object> typed = (Map<String, Object>) raw;

// But this will fail...
for (String key : typed.keySet()) {
System.out.println(key);
}
}
}

В основному компілятор вставляє команду для кожного доступу до ключів або значень, і ці приховані касти можуть вийти з ладу - але вони "повторно ні на тому самому місці, в якому відливали Map<String, Object>.


1 для відповіді № 2

Ви ніколи не отримаєте ClassCastException для неперевіреного складу, тому що це "визначення того, що таке неперевірений склад".

ви воляоднак отримайте це виключення зсередини convert метод, якщо він намагається змінити ключі карти на String.

Але в будь-якому випадку ці два питання не пов'язані між собою: дженерики о складання часу тип безпеки та ClassCastExceptions щодо захисту безпеки типу під час виконання.

Отже, чи достатньо блоку ловлі, щоб уникнути проблем з типом у вашому випадку не відомо. Це може Буде достатньо, але загальних гарантій точно немає.