Java assert нарушен? - PullRequest
       37

Java assert нарушен?

25 голосов
/ 03 мая 2010

Обдумывая вопросы, я недавно обнаружил ключевое слово assert в Java. Сначала я был взволнован. Что-то полезное я еще не знал! Для меня более эффективный способ проверить правильность ввода параметров! Уй учусь!

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

Это звучит как кошмар. Если я утверждаю, что не хочу, чтобы код продолжал работать, если вход listOfStuff равен null, с какой стати я бы хотел, чтобы это утверждение игнорировалось? Похоже, что если я отлаживаю часть производственного кода и подозреваю, что listOfStuff, возможно, ошибочно был передан null, но я не вижу никаких доказательств того, что это утверждение сработало, я не могу доверять этому 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;

Спасибо всем, кто нашел время, чтобы помочь мне понять эту функцию; это очень ценится.

Ответы [ 12 ]

1 голос
/ 03 мая 2010

Это прямо не отвечает на ваш вопрос о assert, но я бы рекомендовал проверить класс Предварительные условия в guava / google-collection, Это позволяет вам писать такие хорошие вещи (используя статический импорт):

// throw NPE if listOfStuff is null
this.listOfStuff = checkNotNull(listOfStuff);

// same, but the NPE will have "listOfStuff" as its message
this.listOfStuff = checkNotNull(listOfStuff, "listOfStuff"); 

Кажется, что-то вроде этого может быть тем, что вы хотите (и его нельзя отключить).

0 голосов
/ 03 мая 2010

Утверждения должны указывать на проблему в коде, которая может быть исправлена, или в качестве помощи при отладке. Вы должны использовать более разрушительный механизм для более серьезных ошибок, таких как остановка программы.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...