Во время обсуждения вопросов я недавно обнаружил ключевое слово assert
в Java. Сначала я был в восторге. Что-то полезное я еще не знал! Более эффективный способ проверить правильность входных параметров! Yay learning!
Но потом я посмотрел поближе, и мой энтузиазм был не столько "закаленным", сколько "полностью выдутым" одним простым фактом: вы можете отключить утверждения. *
Это звучит как кошмар. Если я утверждаю, что я не хочу, чтобы код продолжал идти, если вход listOfStuff
равен null
, почему я бы хотел, чтобы это утверждение игнорировалось? Похоже, если я отлаживаю кусок производственного кода и подозреваю, что listOfStuff
, возможно, был ошибочно передан null
, но не видит никаких доказательств logfile, вызывающих это утверждение, я не могу доверять, что listOfStuff
действительно получил отправленное действительное значение; Я также должен учитывать возможность того, что утверждения могут быть полностью отключены.
И это предполагает, что я один отлаживаю код. Кто-то, кто не знаком с утверждениями, может увидеть это и предположить (вполне разумно), что если сообщение подтверждения не появляется в журнале, listOfStuff
не может быть проблемой. Если ваша первая встреча с assert
была в дикой природе, вам даже пришло бы в голову, что ее можно полностью отключить? Это не похоже на опцию командной строки, которая позволяет отключить блоки try/catch в конце концов.
Все это подводит меня к моему вопросу (и этот является вопросом, а не оправданием для разглагольства! Я обещаю!):
Что мне не хватает?
Есть ли какой-то нюанс, который делает реализацию Java assert
гораздо более полезной, чем я за это благодарю? Является ли возможность включить/отключить его из командной строки, действительно невероятно ценную в некоторых контекстах? Я как-то неправильно понимаю его, когда я предполагаю использовать его в производственном коде вместо утверждений типа if (listOfStuff == null) barf();
?
Я просто чувствую, что здесь что-то важное, что я не получаю.
* Хорошо, технически говоря, они фактически отключены по умолчанию; вы должны уйти с дороги, чтобы включить их. Но все же вы можете полностью их выбить.
Изменить: Запрошенное просвещение, полученное просвещение.
Понятие, что assert
- это прежде всего инструмент отладки, идет длинный, длинный путь, чтобы сделать его имеющим смысл для меня.
Я все еще не согласен с тем, что вводные проверки для нетривиальных частных методов должны быть отключены в производственной среде, потому что разработчик считает, что плохие входы невозможны. По моему опыту, зрелый код производства - сумасшедшая, растянутая вещь, разработанная в течение многих лет людьми с разной степенью мастерства, ориентированными на быстро меняющиеся требования разной степени здравомыслия. И даже если плохой ввод действительно невозможен, кусок неряшливого кода обслуживания через шесть месяцев может изменить это. Ссылка gustafc предоставлена (спасибо!) включает это в качестве примера:
assert interval > 0 && interval <= 1000/MAX_REFRESH_RATE : interval;
Отключение такой простой проверки в производстве поражает меня, как глупо оптимистично. Однако это различие в философии кодирования, а не сломанной функции.
Кроме того, я могу определенно увидеть значение чего-то вроде этого:
assert reallyExpensiveSanityCheck(someObject) : someObject;
Спасибо всем, кто нашел время, чтобы помочь мне понять эту особенность; это очень ценится.