sonarLint жалуется, что нулевые указатели не должны разыменовываться (squid:S2259), несмотря на то, что эта возможность обрабатывается

Итак, у меня есть проблема с SonarLint, к которой я не знаю, как подступиться.

скажем, у меня есть класс с методом

public class Class(RemoteContext context)
    RemoteContext context = context;

    public void String method(String data) {
        if(data == null)
            context.raiseException("data can't be null");

        //do stuff with data like data.get();
    }

Когда я анализирую этот класс с помощью sonarLint (3.2.), я получаю, что нулевой указатель не должен быть разыменован.

Итак, мой вопрос. Как решить эту проблему? context.RaiseException остановит выполнение метода, поэтому я думаю, что это ложное срабатывание.

Приложение имеет много случаев (классов/методов) с этой проблемой. Поэтому я думаю, что аннотации - это излишество (уродливый код повсюду). Я также мог бы набирать return после каждого вызова raiseException(), но у меня сложилось впечатление, что это не «путь программистов».

Я предполагаю, что лучше всего было бы написать собственное правило.

Я просматривал темы и гуглил, но не нашел ничего полезного для этого случая, когда мне приходится делать «противоположное» тому, что на самом деле делает сонар. Не поднимая вопрос, а как бы «давая зеленый свет» методу?

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


person user3219947    schedule 28.11.2017    source источник
comment
Какова подпись метода RemoteContext#raiseException?   -  person T.J. Crowder    schedule 28.11.2017
comment
Больше одного. 6 разных, если быть точным   -  person user3219947    schedule 28.11.2017
comment
Только один из них используется выше и, следовательно, актуален.   -  person T.J. Crowder    schedule 28.11.2017
comment
public void raiseException (int Status, String logMessage, String messageID, Map errorMessages)   -  person user3219947    schedule 28.11.2017
comment
Да, это выдает RunTimeException, извините, я сначала не понял, что вы хотели   -  person user3219947    schedule 28.11.2017
comment
context.RaiseException остановит выполнение метода: но sonarLint не может этого знать.   -  person Raedwald    schedule 19.08.2019


Ответы (2)


Если RemoteContext — это класс, которым вы управляете, и вы действительно не хотите использовать обычный шаблон new ExceptionType(...), я бы изменил RemoteContext на создание исключения, но не сгенерировал его, и тогда

if (data == null) {
    throw context.buildException("data can't be null");
}

... так что SonarLint, компилятору Java и программистам, работающим над кодом позже, будет ясно, что выполнение метода останавливается в этой точке (поскольку «вызов исключения» может означать много вещей).

(Да, это означает изменение множества мест, которые у вас есть, но этого можно достичь с помощью относительно простого поиска и замены.)

person T.J. Crowder    schedule 28.11.2017
comment
Не совсем под моим контролем, сомневаюсь, что такой подход возможен - person user3219947; 28.11.2017
comment
@ user3219947: Ну, в этот момент вы пытаетесь найти обходной путь для плохих практик; компилятор Java, SonarLint и люди, занимающиеся обслуживанием позже, не могут знать, что выполнение метода на этом заканчивается (за исключением логического вывода, зная имя метода raiseException). Добавление return; после того, как кажется вашим вторым лучшим (с большим отрывом) решением. - person T.J. Crowder; 28.11.2017
comment
Соответствует моей идее ... нужно было сначала прочитать ваш ответ ;-) - person GhostCat; 28.11.2017

Нет действительно элегантных способов решить эту проблему. Что работает:

 public SomeException createAndThrow() {
   throw new SomeException();
 }

Для использования как:

 throw createAndThrow();

Это дает вам «двойную блокировку»:

  • ваш служебный метод выбрасывает ... но в случае, если он не выбрасывает
  • вы предполагаете, что объект исключения просто возвращается, поэтому давайте бросим его

Другие языки, такие как C++, позволяют даже выразить: этот метод/функция не поддерживает нормальный возврат. Но Java не предлагает этого.

person GhostCat    schedule 28.11.2017
comment
Оооо, это действительно умно - и, возможно, гнусно. надо еще подумать... :-) - person T.J. Crowder; 28.11.2017
comment
Конечно, если кто-то сделает return null, все это, вероятно, сломается очень некрасиво. - person GhostCat; 28.11.2017