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

@Nullable входной сигнал в интерфейсе Google Guava триггеры FindBugs

Интерфейс com.google.common.base.Function (из Google Guava) определяет apply как:

@Nullable T apply(@Nullable F input);

Метод имеет следующую заметку javadoc:

@throws NullPointerException if {@code input} is null and this function does not accept null arguments.

FindBugs жалуется на мою реализацию функции:

private static final class Example implements Function<MyBean, String> {
    @Override
    @Nullable
    public String apply(@Nullable MyBean input) {
        if (null == input) {
            throw new NullPointerException();
        }
        return input.field;
    }
}

с предупреждением с высоким приоритетом:

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE, приоритет: высокий

вход должен быть ненулевым, но отмечен как nullable

Этот параметр всегда используется так, чтобы он был ненулевым, но параметр явно аннотируется как Nullable. Либо использование параметра, либо аннотации неверно.

Моя функция не поддерживает входы null и генерируется исключение, если это так. Если я правильно понимаю, FindBugs рассматривает это как требование для непустого.

Мне кажется, что это противоречие: input @Nullable, но метод @throws NullPointerException, когда он равен нулю. Я что-то упускаю?

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

Кто ошибается в использовании @Nullable аннотации, FindBugs, Guava или меня?

4b9b3361

Ответ 1

Ваша реализация неверна;)

В основном документы говорят (я перефразирую и подчеркиваю):

@throws NullPointerException, если input имеет значение null и бетон функция не принимает нулевые аргументы

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

private static final class Example implements Function<MyBean, String> {
    @Override
    @Nullable
    public String apply(@Nullable MyBean input) {
        return input == null ? null : input.field;
    }
}

Во втором случае:

private static final class Example implements Function<MyBean, String> {
    @Override
    @Nullable
    public String apply(MyBean input) {
        if (null == input) {
            throw new NullPointerException();
        }
        return input.field;
    }
}

В обоих примерах допускается null.

EDIT:

Обратите внимание, что Guava использует @javax.annotation.ParametersAreNonnullByDefault для всех пакетов, поэтому, если присутствует @Nullable, это означает "приостановить глобальный @Nonnull и разрешить здесь nulls", и если это не означает, что здесь запрещены запреты ".

Тем не менее, вы можете использовать аннотацию @Nonnull для вашего аргумента или @ParametersAreNonnullByDefault в пакете, чтобы сообщить, что аргумент функции FindBugs не может быть нулевым.

ИЗМЕНИТЬ 2:

Выключается этот случай известен как проблема, см. комментарий № 3 (от ведущего гигава Гувева Кевина Бурриллиона, о его разговоре с Биллом Пью, Findbugs '):

Моя рекомендация была серией личных бесед с Биллом Пью. Он недвусмысленно утверждал, что @Nullable означает только то, что некоторые подтипы может принять null. И это, по-видимому, подтверждается поисковыми машинами для нас - наш код довольно легко передает проверки на недействительность (хотя мы должен снова проверяться, поскольку это конкретное изменение функции было выполнено).

Ответ 2

Маркировка параметра @Nonnull устраняет проблему из findbugs.

Ответ 3

Кажется, что по умолчанию функции Guava Google по умолчанию являются @Nullable - я получаю ошибки Findbugs, заявляя, что "результат должен быть ненулевым, но отмечен как nullable", когда не было аннотации. Добавление @Nonnull к объявлению функции следующим образом помогло:

new Function<Object, Object>() {
            @Nonnull
            public Object apply(@Nonnull Object object) {

и теперь Findbugs счастлив. Спасибо всем