Должны ли мы утверждать каждое создание объекта в java?

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

  •  12-09-2019
  •  | 
  •  

Вопрос

Звучит как глупый вопрос с очевидным ответом :)

И все же я рискнул спросить, просто будь уверен вдвойне.

Мы действительно используем утверждения, подобные приведенным ниже

ArrayList alProperties = new ArrayList();

assert alProperties != null : "alProperties is null";

Проблема в том, что создать небольшой и простой документ, которому можно следовать, по утверждениям, сложно.Есть много книг по asserts, но в идеале я хотел бы дать начинающему программисту очень простые рекомендации по использованию чего-то вроде asserts.Кстати, проверяет ли какой-нибудь инструмент, такой как pmd, правильное использование asserts?

Заранее благодарю.

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

Решение

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

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

Существует несколько довольно кратких рекомендаций по использованию утверждений в Sun's Программирование с помощью утверждений.В этой статье рекомендуется использовать утверждения для таких вещей, как Внутренние инварианты, инварианты потока управления, а также предварительные условия, постусловия и инварианты классов.

Нет, вы не хотите проверять создание объекта.

Если создание объекта завершится неудачей, jvm выдаст OutOfMemoryError , и если это произойдет, вы, скорее всего, все равно будете неисправны.

это все равно что не доверять JVM.Относительно того, что вы принимаете как данность, вы должны где-то провести черту...

Это утверждение только загромождает ваш код, оно было бы эквивалентно этому утверждению:

boolean a = true;
assert a : "A should be true"

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

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

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

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

Если вы вызываете вещи извне, вы бы также использовали assert, например, в вашем примере, если бы у вас было ArrayList.Create(), тогда вы могли бы выбрать проверку утверждения для null.Но только потому, что вы не доверяете другому коду.Если бы вы написали этот код, вы могли бы поместить утверждение (комментарий или иное) в сам фабричный метод.

int max(int[] a, int n) {
  assert n <= a.length : "N should not exceed the bounds of the array"
  assert n > 0 : "N should be at least one"

  // invariant: m is the maximum of a[0..i]
  int m = a[0];
  for( int i = 1; i < n; n++ ) {
    if( m < a[i] )
      m = a[i];
  }

  // if these were not basic types, we might assert that we found
  // something sensible here, such as m != null
  return m;
}

В Java каждый вызов new возвращает либо ненулевую ссылку на новый объект, либо вызывает Исключение или Ошибку.В первом случае ваше утверждение истинно, во втором случае утверждение не будет достигнуто, потому что вы заканчиваетесь следующим соответствующим блоком catch.

Это утверждение проверяет, не нарушена ли ваша Java-реализация, и в этом случае вы даже не можете полагаться на утверждение.Так что я бы не стал делать подобных заявлений.Используйте assert для ограничений на объекты, которые не применяются языком (например, если вашему методу передан параметр, который равен null, но не должен быть таким).

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

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

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

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

Если это утверждение завершится неудачей, я думаю, мне пора искать другую работу, потому что компьютер ведет себя не так, как должен, и когда это произойдет, начнется настоящий ад!

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