Можно ли в Java try-catch отлавливать параметризованный кастомный exception и делать разную логику в catch в зависимости от параметра
Что проверяют
Здесь ловушка в слове «параметризованный». Интервьюер проверяет, знаете ли вы, что дженерик-исключение в Java объявить нельзя, и умеете ли решить исходную задачу по-другому. Следом обычно спрашивают, почему компилятор это запрещает.
Как отвечать
Разведите два смысла вопроса.
Если параметр это дженерик, то нет. Класс с параметром типа не может наследоваться от Throwable, даже косвенно: class MyException<T> extends Exception не скомпилируется. Причина в стирании типов: в рантайме MyException<String> и MyException<Integer> один и тот же класс, и catch не смог бы их различить. По той же причине в catch нельзя указать переменную типа. В throws она допустима: <E extends Exception> void run() throws E.
Если параметр это поле исключения, то да. Ловите один тип и ветвитесь по его состоянию:
- enum вместо числового кода:
catch (PaymentException e)иswitch (e.getReason())по значениямINSUFFICIENT_FUNDS,CARD_EXPIRED. В switch-выражении безdefaultкомпилятор не пропустит необработанное значение; - иерархия исключений: отдельные подклассы и несколько блоков
catch, от частного к общему. Часто это чище, чем ветвление внутри одного блока; - multi-catch:
catch (TimeoutException | ConnectException e), когда разные типы обрабатываются одинаково. Типы в списке не должны быть подклассами друг друга; - pattern matching: с Java 21
switchпо детали ошибки изsealed-иерархии с разбором записей (record).
В веб-слое на Spring разную реакцию на исключения обычно выносят в @RestControllerAdvice с методами @ExceptionHandler, а ответ собирают в ProblemDetail.
Где спотыкаются
Пишут дженерик-исключение и узнают об ошибке компиляции только на собеседовании. Запрет стоит в спецификации языка, обойти его нельзя.
В ветке default логируют и глотают исключение. Неизвестный код нужно пробрасывать дальше (throw e), иначе ошибка исчезнет молча.
Ставят catch (Exception e) раньше конкретного типа. Такой код не скомпилируется, потому что более частный блок недостижим, а цепочка instanceof внутри общего catch быстро превращает логику в кашу.