Java позволяет создать совершенно новый подтип Throwable, например:
public class FlyingPig extends Throwable { ... }
Теперь, очень редко, я могу сделать что-то вроде этого:
throw new FlyingPig("Oink!");
и, конечно же, в другом месте:
try { ... } catch (FlyingPig porky) { ... }
Мои вопросы:
- Это плохая идея? И если да, то почему?
- Что можно было сделать, чтобы предотвратить этот подтипирование, если это плохая идея?
- Поскольку это невозможно предотвратить (насколько я знаю), какие катастрофы могут возникнуть?
- Если это не такая плохая идея, почему бы и нет?
- Как вы можете сделать что-то полезное из того, что вы можете
extends Throwable?
- Как вы можете сделать что-то полезное из того, что вы можете
Предлагаемый сценарий № 1
Сценарий, в котором я действительно испытывал желание сделать что-то вроде этого, имеет следующие свойства:
- "Событие" - это то, что в конечном итоге произойдет. Ожидается . Это определенно не
Error, и там ничегоExceptionне о том, когда это произойдет.- Поскольку он ожидается, ожидается его
catch. Он ничего не пропустит. Он не "убежит" от любой попыткиcatchобщегоExceptionи/илиError.
- Поскольку он ожидается, ожидается его
- "Событие" происходит крайне редко.
- Когда это происходит, обычно есть глубокая трассировка стека.
Так что, возможно, теперь ясно, что я пытаюсь сказать: FlyingPig является результатом исчерпывающего рекурсивного поиска.
Объект для поиска существует: это только вопрос нахождения его в большом море, которое является поисковым пространством. Процесс поиска будет длинным, поэтому относительно высокая стоимость обработки исключений незначительна. Фактически, традиционная альтернатива управления потоком, использующая флаг boolean isFound, может быть более дорогой, поскольку ее необходимо проверять непрерывно в течение всего процесса поиска, скорее всего, на каждом уровне рекурсии. Эта проверка не удастся 99,99% времени, но абсолютно необходимо распространять условие завершения. В какой-то мере, будучи эффективным, проверка неэффективна!
Просто throw -ing a FlyingPig, когда искомый объект найден, вам не нужно загромождать код с помощью управления флагом boolean isFound. В этом отношении не только очиститель кода, но он может работать быстрее из-за этого упущения.
Итак, чтобы подвести итог, выбор между этими двумя:
- Традиционный подход к управлению потоком
- Используйте
boolean isFound, постоянно проверенный - 99,99% времени, чек - это "отходы", потому что он все равно будет
false - Когда он в конечном итоге превратится в
true, вы перестанете рекурсировать, и вы должны убедиться, что сможете нормально расслабиться до начального вызова.
- Используйте
-
FlyingPig- Не беспокойтесь ни с какими
boolean isFound. - Если найдено, просто
throw new FlyingPig(); он ожидается, поэтому для него будетcatch. - Отсутствует управление флагом
boolean, нет пропущенной проверки, если вам нужно продолжать, без учета ручного размотки рекурсии и т.д.
- Не беспокойтесь ни с какими
Вопросы:
- Является ли эта методика (ab) использованием исключения действительным? (Есть ли это имя?)
- Если допустимо, следует
FlyingPig extends ThrowableилиExceptionпросто отлично? (хотя в его обстоятельствах нет ничего исключительного?)