#java #spring #spring-boot #sonarqube
#java #весна #весенняя загрузка #sonarqube
Вопрос:
public List<LawOfficeDetailEntity> getLawOfficeByManagementUnitId(Long managementUnitId, Boolean statusless) {
List<LawOfficeDetailEntity> entities = lawOfficeDetailRepository.findByManagementUnitType(String.valueOf(managementUnitId));
return (statusless == null || statusless == false) ? entities.stream().filter(office -> office.getValidityStatus() == 1).collect(Collectors.toList()) : entities;
}
У меня есть ошибка гидролокатора «удалить буквальное «ложное» логическое значение» без статуса == false. Как я могу это исправить?
Комментарии:
1. заменить
statusless == false
на!statusless
2. Вы читали, как Sonar объясняет проблему? rules.sonarsource.com/java/RSPEC-1125
3. Разве sonarqube также не дает объяснения (с примерами) проблем, которые он обнаруживает?
Ответ №1:
Поскольку вы используете Boolean
, а не примитивный тип boolean
, вам не следует сравнивать его с. ==
Что вы можете сделать, это: statusless == null || !statusless.booleanValue()
Комментарии:
1. Даже
!Boolean.TRUE.equals(statusless)
должно работать.2. «вы не должны сравнивать его с ==» это только в том случае, если вы сравниваете его с другим не примитивным. Поскольку оно сравнивается
false
,statusless
оно распаковывается и==
является правильным.3. @AndyTurner с более широкой точки зрения, наличие трех состояний «boolean» определенно неверно. Сводя вопрос к простому «заставить sonar заткнуться», ваш совет сводится к «просто закройте глаза и игнорируйте предупреждение»? Это.. не то, о чем просил OP. Предупреждение sonar касается НЕ риска сравнения значений в штучной упаковке с
==
— это просто избыточноеx == true
/x == false
в логических сравнениях; sonar хочет, чтобы выx
!x
вместо этого написали / . Таким образом, в обоих смыслах вопроса,==
здесь, безусловно, неверно.4. @rzwitserloot Я комментирую этот ответ, а не вопрос.
5. @AndyTurner Да, это сработало бы, но компилятору пришлось бы его распаковать. Это не имеет большого значения, но я думаю, что SonarQube выделит это как запах кода для ненужной распаковки логического значения. Итак, для исправления запаха кода вы получите другой.
Ответ №2:
Учитывая, что этот вопрос касается инструмента для компоновки, поэтому речь идет исключительно о правильном стиле кода и гигиене, и поэтому вопрос немного сложный: да, есть способ «избежать предупреждения сонара», но это все равно, что передать базуку ребенку: тоти единственная причина использования sonar — написать правильный код, а самый быстрый и простой способ «избежать предупреждения сонара» ухудшает ваш код.
Итак, я лучше всего объясню, что на самом деле не так с этим кодом!
—
Основная проблема заключается в том, что вы превратили логическое значение в троичное состояние: это может быть true
, false
, ИЛИ null
, и это имеет смысл только в смысле SQL: это null
указывает на unknown, not applicable или еще не установлено. Во всех 3 таких случаях обработка null
as false
просто неверна.
Что бы ни делало statusless be null
? Исправьте это. Сделайте так, чтобы это было не так. Если это то, что вы получаете из другой системы, исправьте это в другой системе (пример: если это логический столбец db с нулевым значением, задайте ему ненулевое ограничение и FALSE
значение по умолчанию), или, если вы не можете исправить это в другой системе, исправьте это немедленно, как только данныепоступает на «вашу сторону» кода.
Как только вы все это сделаете, возможность statusless
быть null
исчезнет.
ПРИМЕЧАНИЕ: инструменты компоновки, такие как sonar, — действительно плохая идея, если вы полностью не понимаете каждое предупреждение, которое оно вам выдает. Инструмент компоновки имеет тенденцию находить проблемы с кодом среднего и низкого уровня и редко может обнаруживать высокоуровневые, более важные проблемы с кодом, как в данном случае.
Если каким-то образом вы хотите проигнорировать этот совет, поскольку вы определили, что продолжение работы с лежащей переменной (‘boolean’, даже ‘Boolean’, довольно сильно предполагает либо 2 состояния, либо, возможно, 2 состояния возможность оставаться неустановленным, но, конечно, не «три состояния») в любом случае, выможно просто заменить statusless == null || statusless == false
на: !Boolean.TRUE.equals(statusless)
. Boolean.TRUE
отчеты false
, если вы не передадите true
значение — так statusless
или false
null
иначе, TRUE.equals(that)
вернутся false
. Переверните это false
true
и вуаля.
Вы не можете писать !statusless
, потому что это вызовет NPE, если statusless
значение равно null.
Но подождите! Альтернативная интерпретация!
Возможно, это логическое значение действительно должно представлять пограничное приемлемое понятие «это значение либо true, либо false, либо еще не установлено / не применимо к этой ситуации», и в этом случае NPE — это именно то, что вам нужно здесь: вы не можете определить, следует ли фильтровать по статусу достоверностиили нет, и все же вы должны здесь, поэтому этот код не может быть продолжен, и ошибка заключается в том, что вызывающий объект установил недопустимое состояние перед вызовом этого метода. В этом случае вы действительно просто хотите return !statusless ? ... : ...;
Комментарии:
1. «В этом случае вы действительно просто хотите» в этом случае лучше создать параметр
boolean
; тогда вы не скрываете тот факт, что этот метод выдаст NPE, если передано нулевое значение. Если вы задаете параметру логическое значение, распаковка происходит в коде вызывающего, а не в этом коде, что дает понять, чью ответственность следует избегать.2. Да, если оно передается как параметр, обязательно сделайте его строчным.