Можно ли в Java объявить блок catch для исключения с конкретным generic-типом (например, Exception)?

«Можно ли в Java объявить блок catch для исключения с конкретным generic-типом (например, Exception)?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, напрямую объявить такой блок catch нельзя. Механизм стирания типов (type erasure) удаляет информацию о generic-параметрах во время выполнения, поэтому JVM не может различить, например, Exception<String> и Exception<Integer>.

Обходные пути и их ограничения:

  1. Проверка типа внутри блока catch:
    try {
        someRiskyMethod();
    } catch (Exception e) {
        if (e instanceof SomeGenericException) {
            // Приведение типа, но без generic-параметра
            SomeGenericException ex = (SomeGenericException) e;
            // Дальнейшая обработка
        }
    }
  2. Использование класса-обертки: Создайте непараметризованный подкласс для конкретного типа.
    class StringException extends SomeGenericException<String> {}
    // Теперь можно catch (StringException e)

Рекомендация: В подавляющем большинстве случаев следует избегать generic в исключениях. Используйте проверенные исключения с четкой семантикой или передавайте параметризованные данные внутри стандартных исключений.