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

Почему мы не можем использовать утверждение для публичных методов?

Почему мы не можем использовать утверждение для общедоступных методов?

Я где-то читал

"Утверждение неуместно публично методов, поскольку метод гарантирует что он всегда будет обеспечивать соблюдение проверки аргументов. Общественный метод должен проверить его аргументы, независимо от того, утверждений. Кроме того, assert не бросает исключение указанного типа. Это может вызывать только AssertionError".

Итак, не применимо ли это для частного метода?
Я не совсем понял это утверждение

4b9b3361

Ответ 1

Важным отличием является то, считаете ли вы, что неправильное значение является результатом

a) Ошибка программирования, которая должна быть исправлена ​​в коде.

b) Ошибка ввода, которая не может быть предотвращена в коде и вместо этого должна обрабатываться во время выполнения.

В первом случае вы должны использовать assert, так как код программы должен быть исправлен. Если это более поздний случай, вы должны использовать соответствующее исключение Runtime или check.


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

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

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

Ответ 2

Утверждения не должны использоваться для проверки аргументов в публичных методах по следующим причинам:

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

Пример:

    /**
     * @throws ArithmeticException if divisor is zero
     */ 
    public void int divide(int divisor) {
        if (divisor == 0) {
            throw new ArithmeticException("Cannot divide by zero");
        }
        ...
    }

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

Ответ 3

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

Конечно, утверждение не для проверки параметров.

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

Затем произойдет одно из следующих действий:

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

Ответ 4

Вероятно, это исходный источник из руководства по Java SE "Программирование с утверждениями".

Не используйте утверждения для проверки параметры публичного метода. утверждать неуместно, потому что метод гарантирует, что он всегда будет обеспечить проверку аргументов. Это должно проверить его аргументы, или нет утверждения включены. Кроме того, Утверждение конструкции не бросает исключение указанного типа. Это может выдать только ошибку AssertionError.

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

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

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

Ответ 5

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

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

public void update(Object o) {
   int nUpdatedObjects = dao.update(o);
   assert(nUpdatedObjects == 1)
}

В этом случае он служит для validate слоя dao с помощью отказоустойчивого принципа.

Ответ 6

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

Ответ 7

Я даю ответ, который не совсем точно. Конечно, вы можете использовать assert в публичных методах (или где угодно).

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

Но я должен признать, что НИКОГДА не использую утверждения, и что я редко вижу когда-либо утверждения в коде. Я работал всего несколько лет, но в 4 совершенно разных компаниях, над которыми я работал, в коде не было никаких утверждений. Будь то более 10 миллионов строк веб-приложения кода для бронирования авиабилетов, центра управления космическими аппаратами, программного обеспечения для управления гипермаркетом или отслеживания ошибок. Ни один из них не использовал утверждения. У всех компаний были разные потребности и методы. Ничего не используется.

Для меня причина проста. Люди здесь говорят, что утверждения предназначены для отладки. Это здорово. И вы можете отключить их для повышения скорости. Это тоже хорошо... Сначала. Чем сложнее программа, тем больше вы тратите время на отладку. И некоторые ошибки, даже со 100% -ным охватом кода, даже при обширной интеграции и проверке проверки, вы найдете их только в производстве. Просто потому, что ваши пользователи в конечном итоге используют ваше приложение больше, чем вы. И они не будут использовать его так же, как вы.

Это смешно, потому что в журналах производства мы продолжаем видеть stacktraces из кода следующим образом:

catch (MyException e) {
  logger.war("This should never happen",e);
}

Это означает, что вы никогда не знаете, что может произойти в производстве.

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

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

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

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

Ответ 8

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

Например, вы могли бы использовать утверждение, как я это делал, в методе public build() для строителя, чтобы убедиться, что построитель был правильно инициализирован моим собственным внутренним кодом в этом классе (поскольку у меня есть ряд перегруженные конструкторы для него).

Но то, что вы НИКОГДА НЕ должны делать, - это утверждения использования для проверки ARGUMENTS публичных методов. Важное различие. Я думаю, что другие ответы здесь объяснили причины достаточно явно, поэтому я не собираюсь повторять что-либо.

Ответ 9

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

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

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

Ответ 10

Этот запрет применяется только к общедоступным интерфейсам.

Из http://download.oracle.com/javase/6/docs/technotes/guides/language/assert.html#preconditions:

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

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

Для всех остальных случаев утверждения очень ценны и являются краеугольным камнем для "программирования по контракту". См. http://java.sun.com/developer/technicalArticles/JavaLP/assertions для хорошего введения.

  • Java имеет исключенные исключения по какой-либо причине - это много катастрофических сбоев, которые обычно не должны быть пойманы. Любое выделение памяти может вызывать OutOfMemoryError. Неудачное утверждение (ошибка в клиентском коде, которая предоставила неверный аргумент нашему API), не менее катастрофична.

  • Верно, что утверждения можно отключить. Однако этого никогда не должно быть сделано. Только не делай этого. Если вы знаете, что кто-то, кто запускает ваш код, отключит утверждения, вы всегда можете создать тривиальный собственный класс утверждения, который нельзя отключить. Принцип использования утверждений не изменяется.

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

Ответ 11

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

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

Теперь вопрос, который может возникнуть в вашем сознании, - это использование утверждений для проверки значений аргументов частного метода?

Ну, причина в том, что частные методы могут быть вызваны из класса, который он определен (либо из метода экземпляра, либо из статического основного метода). Разработчик класса infact знает все о приватном методе - что он делает, как вызвать его и какие значения параметров передать. Значения аргументов частного метода частного можно безопасно проверить с помощью утверждений.