Javax.annotation.Nonnull против утверждения

Я использую Findbugs и javax.annotation.Nonnull для параметров метода.

В частных методах я обычно добавляю строку assert, чтобы проверить нуль, например

private void myMethod(@Nonnull String str) {
    assert str != null
    ....

Последняя версия Netbeans (7.3rc2) сообщает, что проверка assert не нужна (из-за аннотации Nonnull). Я не совсем уверен, что это ошибка Netbeans или нет.

Можно ли удалить строку assert, потому что я указал аннотацию @Nonnull?

Насколько я понимаю, аннотация используется только во время статического анализа, тогда как assert, когда он включен, активен во время выполнения, поэтому двойки не являются альтернативными.

Ответ 1

Утверждение оценивается во время выполнения, аннотация помогает FindBugs уловить проблемы во время анализа до выполнения. Поскольку обе проверки не противоречат друг другу, вы можете сохранить их обоих. Мне было бы неприятно, если бы моя IDE сказала мне удалить утверждение.

Ответ 2

Netbeans прав. Если вы считаете, что это может быть null: удалите аннотацию. Если вы знаете, что это невозможно, удалите assert.

Если есть вероятность, что ваш метод может быть вызван с нулевым значением, то @Nonnull аннотации не должно быть.

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

Ответ 3

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

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

Если вы все еще чувствуете, что утверждение в приватном методе необходимо, я думаю, вы можете использовать инъекцию байт-кода. Например, вот плагин maven для ввода нулевой проверки. Извините, это мой личный проект, но он работает со мной. Думаю, это может удовлетворить ваши потребности. https://github.com/KengoTODA/jsr305-maven-plugin

Ответ 4

Я нашел другое решение, так как думал о своих предупреждениях IDE.

Вначале я чувствовал, что IDE ошибается. Я программист-параноик и хочу иметь ярлык для документирования и статического анализа. И проверка времени выполнения в случае, когда я когда-либо использую его из отражения, или другого языка JVM или чего-то, что не подвергается статически анализу, поэтому я подумал, что это неправильно чтобы предупредить меня и сказать, что инструкция assert(x != null) не нужна.

Но потом я подумал о том, как утверждения могут быть удалены в зависимости от статуса флага -ea, переданного Java в Runtime, и что в некотором роде assert и @Nonnull действительно являются проверками только для разработки.

Оказывается, существует реальная проверка времени выполнения, которая может быть вставлена ​​(Java 7+) Objects.requireNonNull, которая выкинет NullPointerException и не может быть удалено с помощью утверждения -ea. Я думаю, что я предпочту это сделать с моим шаблоном assert(x != null); use(x);.

public ConstructorForClass(@Nonnull Type x) {
  this.x = Objects.requireNonNull(x);
  //...
}