Как исправить эту критическую проблему «возможного разыменования нулевого указателя» в Сонаре?

#java #nullpointerexception #sonarqube

#Ява #исключение nullpointerexception #гидролокатор

Вопрос:

Ниже приведен рассматриваемый метод.

 public String getCarById(Integer carId) {  ResponseEntitylt;CarStringgt; response = rTempl.getForEntity(url, CarString.class,  of("car-id", carId.toString()));  log.debug("code: {}", response.getStatusCode());  return Objects.requireNonNull(response.getBody()).getCarString(); }  

Полная ошибка заключается в следующем.

 Possible null pointer dereference in lt;packagegt;.CarRegistryClient.getCarById(Integer) due to return value of called method  

Objects.requireNonNull() Недостаточно ли использовать гидролокатор?

ОБНОВЛЕНИЕ: В метод добавлен отсутствующий, но соответствующий код. Теперь ни один код не пропал.

Комментарии:

1. response может быть нулевым. Хотя сообщение об ошибке сбивает с толку.

2. Эта ошибка сонара появляется, если сонар считает, что NPE неизбежен (т. Е. Существует путь кода, который гарантирует это). В вставленном вами коде такого пути нет; очевидно, что в коде, который вы пропустили, что-то есть. Например, возможно, код, который вы пропустили, указывает, что response он либо определенно равен нулю, либо вы проверяете значение null response , что заставляет сонар идентифицировать «ответ» как потенциально нулевой. Отдельно ваши объекты.requireNonNull здесь совершенно бесполезны; удалите его. (rNN выбрасывает NPE; разыменование, которое вы делаете здесь, также делает. Нет смысла в вашем вызове rNN).

3. @rzwitserloot: Я добавил недостающий, но явно релевантный код обратно в фрагмент кода в моем вопросе.

Ответ №1:

Как ни странно, это было исправлено, и Сонар был доволен.

 public String getCarById(Integer carId) {  ResponseEntitylt;CarStringgt; response = rTempl.getForEntity(url, CarString.class,  of("car-id", carId.toString()));   CarString responseBody = response.getBody();  assert responseBody != null   log.debug("code: {}", response.getStatusCode());  return response.getBody().getCarString(); }  

Я все еще не понимаю, чем это отличается от моего предыдущего решения с помощью Objects.requireNonNull() .

Ответ №2:

Скорее всего rTempl.getForEntity , метод явно объявлен как потенциально возвращаемый null , и ваш код затем просто разыменовывает то, что getForEntity вам дали, ничего не проверяя. Ваш requireNonNull код проверяет, response.getBody() возвращает ли он ненулевое значение; он не проверяет, является ли response он сам ненулевым.

И код все еще отсутствует. Чем может быть rTempl?