Я определенно могу вспомнить ситуации, в которых предпочел бы , чтобы исключение было статическим внутренним классом, а не просто классом в том же пакете.
Кажется, причины этого не делатьбыть:
- Соединение исключения с классом, который выбрасывает его, делает его неуместным повторное использование в других контекстах
- Никто другой не делает это
Я делаюне найти ни одного из этих аргументов вообще убедительным.
Для первого пункта, почему эта гипотетическая будущая возможность для повторного использования возникает в том же пакете?Этот аргумент приводит к выводу, что мы должны поместить все классы исключений как можно выше в иерархию пакетов, чтобы при обнаружении будущей возможности повторно использовать то же исключение нам не нужно вводить зависимость от того, где оно было первоначально определено.
Но даже без точки "доведенных до крайности", рассмотрим исключение, предназначенное для передачи того, что классу Foo
был дан неверный ввод.Если я назову это Foo.InvalidInput
, название будет коротким, и ассоциацию с Foo
невозможно пропустить.Если я помещу его вне класса Foo
и назову его FooInvalidCriteria
, то я все равно не смогу повторно использовать его из класса Bar
, не изменив его имя (эквивалентно изменению его местоположения).
Нохуже всего, если я оставлю его снаружи Foo
и оставлю его общее имя, например InvalidInput
.Затем, когда я позже пойму, что Bar
может иметь неверный ввод, я начну выдавать это исключение.Все компилируется и работает нормально, только теперь все места, которые ловили InvalidInput
и предполагая, что они обрабатывали ошибки из Foo
, теперь могут также обрабатывать ошибки из Bar
, если Foo
использует внутреннее Bar
втаким образом, это может вызвать исключение.Это может легко привести к сбою кода.
Реальность такова, что за исключением исключения, которое ранее задумывалось как конкретно указывающее на ситуацию, возникающую в одном классе, и повторное использование его в качестве общего класса ошибок, является интерфейсом . изменение, а не только изменение внутренней реализации.В целом, чтобы сделать это правильно, вы должны повторно посетить все сайты, на которых перехвачено исключение, и убедиться, что они по-прежнему корректны, поэтому компилятор расскажет вам обо всех используемых сайтах (поскольку вам нужно изменитьимя и / или путь импорта) это хорошая вещь.Любое исключение, которое вы могли бы сделать статическим внутренним классом, не подходит для повторного использования в других контекстах, независимо от того, делаете ли вы его внутренним классом или нет.
И что касается второй точки... "никто больше этого не делает" никогда ни на что не влияет.Либо это действительно неправильно, поэтому будут другие причины не делать этого, поэтому аргумент «никто другой не делает» не нужен.Или это не так.И это не похоже на то, что этот конкретный пример будет ужасно сложным и трудным для понимания, поэтому даже аргумент «это неожиданно, так что у людей возникнут проблемы с этим, даже если это хорошая теоретическая идея», является очень сильным.