Как исправить "Небезопасную интерпретацию типа возвращаемого метода" в анализе нулевых аннотаций Eclipse - PullRequest
0 голосов
/ 19 июня 2020

Использование Eclipse 2019-12.

Я определяю такой метод:

public static <T> T execute(@NonNull Supplier<T> action) {
  return action.get();
}

Теперь, если я сделаю это:

public @NonNull String foo() { return ""; }

public String doSomething() {
  return MyClass.execute(() -> foo());
}

Eclipse показывает информационное / предупреждающее сообщение в doSomething теле, говорящее:

Unsafe interpretation of method return type as '@NonNull' based on substitution 'T=@NonNull String'. Declaring type 'MyClass' doesn't seem to be designed with null type annotations in mind

Итак, я могу понять, что имея MyClass.execute(Supplier), возвращая T и передавая Supplier<T>, где T это @NonNull не обязательно означает, что возвращаемый тип также @NonNull, потому что в целом MyClass.execute(Supplier) может быть реализовано следующим образом:

public static <T> T execute(Supplier<T> action) {
  if(action.getClass().getSimpleName().startsWith("a"))
    return null;
  return action.get();
}

в этом случае, даже если указанное Supplier s T переменная типа @NonNull, MyClass.execute(Supplier) по-прежнему возвращает null в некоторых случаях (и Map.get(Object) является конкретным примером, где он может вернуть null, если указанный ключ отсутствует, даже если Map равен определен как имеющий тип значения @NonNull).

Но теперь, поскольку MyClass.execute(Supplier) находится под моим контролем, я хотел бы понять, есть ли способ записать его в express без двусмысленностей, которые он возвращает type не является нулевым, если указанный Supplier имеет возвращаемое значение @NonNull, в то время как он допускает значение NULL, если указанный Supplier имеет @Nullable возвращаемое значение.

Кроме того, мне не ясно, почему это НЕ генерирует указанную выше информацию / предупреждение:

public String doSomething() {
  return MyClass.execute(() -> "");
}

то есть я просто встроил метод foo() позвоните в приведенном выше примере.

1 Ответ

1 голос
/ 29 июня 2020

Сообщение отображалось неправильно в Eclipse 2019-12 (4.14) и ранее.

В Eclipse 2020-03 (4.15) был улучшен анализ нулевых значений на основе аннотаций. Была добавлена ​​новая проверка ( Небезопасное преобразование аннотированного параметризованного типа в менее аннотированный тип ) и внесено несколько исправлений, которые также влияют на ваш пример.

Сообщения не отображаются в следующий код больше:

public static <T> T execute(@NonNull Supplier<T> action) {
    return action.get();
}

public @NonNull String foo() {
    return "";
}

public @NonNull String doSomething() {
    return MyClass.execute(() -> foo());
}

Но если вы измените foo(), чтобы вернуть значение @Nullable, в строке return Foo.execute(() -> foo()); правильно отображается следующая проблема:

Null type safety (type annotations): The expression of type 'String' needs unchecked conversion to conform to '@NonNull String'

Для нового небезопасного преобразования аннотированного параметризованного типа в менее аннотированный тип см.:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...