Подтвердить что ты не робот

Утверждать хорошую практику или нет?

Хорошо ли использовать Assert для параметров функции для обеспечения их достоверности. Я просматривал исходный код Spring Framework, и я заметил, что они много используют Assert.notNull. Вот пример

   public static ParsedSql parseSqlStatement(String sql) {
    Assert.notNull(sql, "SQL must not be null");}

Вот еще один:

public NamedParameterJdbcTemplate(DataSource dataSource) {
            Assert.notNull(dataSource,
                    "The [dataSource] argument cannot be null.");
            this .classicJdbcTemplate = new JdbcTemplate(dataSource);
        }

        public NamedParameterJdbcTemplate(JdbcOperations classicJdbcTemplate) {
            Assert.notNull(classicJdbcTemplate,
                    "JdbcTemplate must not be null");
            this .classicJdbcTemplate = classicJdbcTemplate;
      }

FYI, Assert.notNull (не оператор assert) определяется в классе util следующим образом:

public abstract class Assert { 
   public static void notNull(Object   object, String   message) {
      if (object == null) {
          throw new IllegalArgumentException  (message);
      }
   }
}
4b9b3361

Ответ 1

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

Например, Java bound проверяет все обращения к массиву во время выполнения. Это делает вещи немного медленнее? Да. Это полезно? Абсолютно! Как только нарушается нарушение, возникает исключение, и программист предупреждается о любой возможной ошибке! Поведение в других системах, в которых обращения к массиву не привязаны к проверке, - БОЛЬШЕ НЕПОСРЕДСТВЕННО! (часто с катастрофическими последствиями!).

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

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

Еще один способ взглянуть на это - думать о утверждениях как о "активных комментариях". Там нет аргументов, что комментарии полезны, но они ПАССИВНЫЕ; вычислительно они ничего не делают. Формулируя некоторые понятия как утверждения вместо комментариев, они становятся АКТИВНЫМИ. Фактически они должны находиться во время выполнения; нарушения будут пойманы.


Смотрите также: преимущества программирования с утверждениями

Ответ 2

Эти утверждения предоставляются в библиотеке и не совпадают с встроенным ключевым словом assert.

Здесь разница: assert не запускаются по умолчанию (они должны быть включены с параметром -ea), а утверждения, предоставленные классом assert, не могут быть отключены.

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

public static ParsedSql parseSqlStatement(String sql) {
    if (sql == null)
        throw new IllegalArgumentException("SQL must not be null");
    ...
}

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

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

Ответ 3

Да, это хорошая практика.

В случае Spring это особенно важно, потому что проверки проверяют параметры свойств и т.д., которые обычно поступают из файлов проводки XML. Другими словами, они проверяют конфигурацию webapp. И если вы когда-либо выполняете какую-либо серьезную разработку на основе Spring, эти проверки будут сэкономить вам часы отладки, когда вы совершите глупую ошибку конфигурации.

Но обратите внимание, что существует большая разница между классом библиотеки Assert и ключевым словом Java Assert, который используется для определения утверждения Java. Последняя форма утверждений может быть отключена во время запуска приложения и НЕ должна использоваться для проверок проверки аргументов, которые вы всегда хотите выполнить. Понятно, что дизайнеры Spring считают, что было бы очень плохой идеей отключить проверку работоспособности конфигурации Webapp... и я согласен.

ОБНОВЛЕНИЕ

В Java 7 (и более поздних версиях) класс java.util.Objects предоставляет requireNonNull метод проверки, если аргумент null и создать исключение. Вы используете его следующим образом:

 SomeType t = ...
 SomeType tChecked = Objects.requireNonNull(t);

или

 SomeType tChecked = Objects.requireNonNull(t, "t should be non-null");

Однако обратите внимание, что этот метод поднимает NullPointerException, а не IllegalArgumentException.

Ответ 4

Основываясь на Sun guide на утверждениях, вы не должны использовать утверждения для проверки аргументов в публичных методах.

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

Ответ 5

В очень больших и плохо спроектированных/поддерживаемых системах, если вы хотите улучшить предсказуемость в методах, которые, скажем, длится 6000 строк, и никто в компании их больше не понимает, может быть полезно использовать ключевое слово assert заставляют среды разработки взрываться, обнаруживая ошибки. Но если бы вы реализовали эти утверждения в производстве, вы могли бы скомпоновать патч, который, хотя и был задуман, исправил проблему. Вы хотите исправить этот плохой патч, открыв его в среде dev, а не в производстве. Таким образом, вы можете включить утверждения во время разработки и отключить их в процессе производства.

Еще одно допустимое использование ключевого слова assert во время разработки - вставить проверки достоверности в алгоритмы, которые должны выполняться в субмиллисекундные времена и достаточно хорошо изолированы от непредсказуемых или непроверенных абонентов. В таком случае вы не сможете позволить себе сохранить проверку действительности в производстве, хотя она по-прежнему очень полезна в разработке. С другой стороны, если источник параметров, которые вы проверяете, непредсказуем или может стать таким (если он определен частично из-за ввода пользователем, например), вы, вероятно, никогда не сможете пропустить проверку даже в процессе производства и должны принять удар производительности как стоимость ведения бизнеса. (В этом последнем случае вы, вероятно, не захотите использовать assert.) Но вы должны выбрать утверждения, чтобы исключить проверку действительности производственного времени только после того, как профилирование говорит вам, что вы просто не можете позволить себе накладные расходы.

Ответ 6

Да, это хорошая идея. Вы выполняете контракт по интерфейсу или классу. Если есть нарушение контракта, вы хотите обнаружить его как можно скорее. Чем дольше вы ожидаете, тем более непредсказуемыми могут быть результаты и тем сложнее диагностировать.

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