Накладные расходы, связанные с Exception vs Throwable в Java

StackOverflow https://stackoverflow.com/questions/2129647

  •  22-09-2019
  •  | 
  •  

Вопрос

Я знаю

throw new Exception();

имеет довольно большие накладные расходы, поскольку создает полный stackTrace и т. д.
Делает

throw new Throwable();

представляют ту же проблему?Наследуется ли такое поведение, или создание Throwable требует меньших (о нет) накладных расходов?

РЕДАКТИРОВАТЬ
Из аналитик С точки зрения пользователя, вводящий неверный пароль, является исключением из обычного порядка выполнения программы.Итак, если у меня есть:

public Session newSession() {  
  validate_user_and_password();   
}

создание исключения UserNotValidException будет звучать правильно с аналитики точка зрения.
Возвращение null или 0 просто звучит неправильно, если ваш код имеет довольно хорошую абстракцию.Я просто хотел знать, смогу ли я реализовать это в коде или мне придется просто оставить это на усмотрение теории.

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

Примечание:Я привел очень простой и глупый пример, это не совсем мой случай.
Заметка 2:Я знаю возвращение null это было бы обычным делом, но от меня требуется правильно абстрагированный и объектно-ориентированный код, и лично я не вижу в этом никакого вреда.

Это было полезно?

Решение

Throwable также создает трассировку стека при его создании.Из Java-документация для Throwable:

throwable содержит снимок стека выполнения своего потока на момент его создания.

Таким образом, с точки зрения накладных расходов на создание трассировки стека не должно быть никакой разницы между Exception и Throwable.

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

Другие советы

Нет, вам нужен собственный подкласс, чтобы избежать этого эффекта.

Exception ex = new Exception() {
    @Override public Throwable fillInStackTrace() {
        return this; // and do nothing else
    }
};

Это создает экземпляр исключения, которое не будет заполнять трассировку стека (создание исключений делегирует fillInStackTrace для фактического заполнения трассировки стека), и поэтому его создание обходится дешево.

При JIT-компиляции на самом деле уже не так много подслушанного вызова Exception на Яве.Но бросая Throwable не сильно отличается, поскольку там вы также получите трассировку стека.

Если вам интересно, есть очень интересная статья под названием «Эффективная обработка исключений Java при JIT-компиляции» (связь).Чтение не лёгкое, но весьма информативное.

Никогда не следует бросать или ловить Throwable. Объем исключения слишком велик.

Как указывалось ранее, исключения следует использовать только там, где это необходимо, а именно:в исключительных обстоятельствах и должны соответствовать ситуации, которая их породила.Помимо этого, поймав Throwable подразумевает множество исключений, таких как OutOfMemoryException.Ошибку такого масштаба невозможно исправить (легко), и разработчик не должен ее обрабатывать.

Throwable является родительским классом Exception.так Exception class унаследован от Throwable.

Throwable vs. Exception

Исключение Java

Как сказал @mangoDrunk: «Throwable — это суперкласс исключений и ошибок».

Вы можете посмотреть исходный код двух классов, чтобы убедиться в этом. Exception не делает ничего, кроме предоставления тех же конструкторов, что и Throwable.Все мясо и, следовательно, накладные расходы живут в Throwable.

Даже если Exception действительно внесло некоторые дополнительные накладные расходы, использование было бы явной чрезмерной оптимизацией Throwable вместо.Используйте правильный инструмент для работы, не приобретайте неправильный инструмент только потому, что он легче.

java.lang.Exception простирается java.lang.Throwable, так что это те же накладные расходы.Из Javadoc:

Класс Throwable — это суперкласс всех ошибок и исключений в языке Java.Только объекты, являющиеся экземплярами этого класса (или одного из его подклассов), создаются виртуальной машиной Java или могут быть созданы с помощью оператора Java throw.Аналогично, только этот класс или один из его подклассов может быть типом аргумента в предложении catch.

Экземпляры двух подклассов, Error и Exception, традиционно используются для обозначения возникновения исключительных ситуаций.Обычно эти экземпляры создаются заново в контексте исключительной ситуации, чтобы включать соответствующую информацию (например, данные трассировки стека).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top