#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
он либо определенно равен нулю, либо вы проверяете значение nullresponse
, что заставляет сонар идентифицировать «ответ» как потенциально нулевой. Отдельно ваши объекты.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?