Работают ли синглтонные исключения? - PullRequest
8 голосов
/ 18 апреля 2009

Мой коллега на работе выступил с докладом о статических фабричных методах (прямо из Effective Java), а затем привел пример его использования для получения статических / одноэлементных исключений.

Это выделило мне красный флаг. Разве исключения не являются состоянием? Разве они не заполнены JVM для информации о трассировке стека? Какую экономию вы действительно получаете от этого, поскольку исключения должны возникать только для исключительных ситуаций?

Мои знания об Исключениях довольно ограничены, поэтому я прихожу к вам с этим: сработают ли синглтонные исключения, и есть ли основания их использовать?

Ответы [ 4 ]

17 голосов
/ 18 апреля 2009

Синглтонные исключения должны быть оптимизацией производительности. Идея состоит в том, что вы исключаете стоимость заполнения трассировки стека при создании исключения, которое обычно является самой дорогой частью исключений.

Если исключение было достаточно уникальным и описательным, а трассировка стека не собиралась использоваться, то синглтон потенциально мог бы быть эффективным. Вы можете создать приложение таким образом, чтобы определенный тип исключения с определенным сообщением всегда означал, что исключение возникло из определенного местоположения. Тогда трассировка стека не будет иметь значения.

В статье от 22 апреля 2003 г. Tech Tips описывается сценарий, в котором вы повторно используете исключение. В этом случае они пытаются играть в сборщик мусора, уменьшая количество созданных объектов. Если вы пропустили вызов populateStackTrace(), вам не придется беспокоиться о потоке.

Как правило, если влияние исключения на производительность вызывает проблемы, это признак того, что исключения используются для логики приложения, и вместо этого следует использовать код ошибки.

В более новых JVM (1.4+, я полагаю) эта «оптимизация» может выполняться JVM автоматически при работе в режиме «-server». Эта оптимизация точки доступа может управляться опцией -XX:+OmitStackTraceInFastThrow.

Лично я бы рекомендовал не использовать шаблон синглтонного исключения [анти-].

3 голосов
/ 18 апреля 2009

Хотя я искренне не согласен с таким подходом, исключения Singleton могут работать в однопоточной среде.

Люди, которые предлагают шаблоны Singleton Exception, как правило, используются в старой парадигме invoke / error / check-error c-стиля и хотят перевести это на один из этих новомодных «объектно-ориентированных» языков.

Это возможно, но я называю это запахом кода.

1 голос
/ 18 апреля 2009

Я могу представить себе ситуацию, когда вы хотите иметь возможность обнаруживать в ваших условиях исключения, было ли исключение уже создано другой частью вашего приложения; Я могу видеть использование единственного исключения для такого рода целей; но это кажется излишним. По сути, это объединяет идею семафора («что-то случилось») с исключением («что-то случилось со мной»).

0 голосов
/ 18 апреля 2009

Если «статический метод фабрики» продолжает возвращать один и тот же объект, это на самом деле не метод фабрики.

Даже java.lang.Throwable имеет два элемента изменяемого состояния: трассировка стека и первоначальная причина, пока новая версия Java не добавит больше. Любой общий Throwable должен будет либо расторгнуть контракт fillInStackTrace, либо вести себя очень странно. Кроме того, повторно использованный Throwable не может разумно изменить сообщение.

Так что вы могли бы сойти с рук, но хотели бы вы? Почти все проблемы с производительностью (и вы обычно не должны бросать исключения слишком часто) сводятся к fillInStackTrace. Если вы это выбьете, то мало смысла в повторном использовании.

(я предпочитаю фразу «метод статического создания» вместо «статический метод фабрики», потому что «фабрика» слишком перегружена.)

...