sonar指导手册(代码检查扫描常见的问题汇总)
阿里巴巴开发规范及sonar相信很多人都用过,今天主要汇总一下,用sonar扫描出来的一些代码问题,今天小编就来聊一聊关于sonar指导手册?接下来我们就一起去研究一下吧!
sonar指导手册
阿里巴巴开发规范及sonar相信很多人都用过,今天主要汇总一下,用sonar扫描出来的一些代码问题。
在开发中,经常一顿猛如虎的操作下来,代码是码完了,单元测试貌似也测了,代码的覆盖率好像也都覆盖了,结果符合预期,貌似可以提测了。刚发提测邮件,领导说,Dot你去review一下代码,看有没有问题,sonar扫描一下看哪些不符合规范。这时有点方,好吧先不提测了,先看看sonar扫了些什么出来。
好在,这个工具很好用,虽然很讨要的扫出来很多不规范的写法及用法,但是也相应的给出答案及正确做法
Move the contents of this initializer to a standard constructor or to field initializers
将这段内容移到初始化构造里或者字段初始化里
错误示范:
class MyClass {
private static final Map<String, String> MY_MAP = new HashMap<String, String>()
{
// Noncompliant - HashMap should be extended only to add behavior, not for initialization
{
put("a", "b"); }
};
}
正确示范:
class MyClass {
private static final Map<String, String> MY_MAP = new HashMap<String, String>();
static {
MY_MAP.put("a", "b");
}
}
或者是用google的guava相关工具包
class MyClass {
// Compliant
private static final Map<String, String> MY_MAP = ImmutableMap.of("a", "b");
}
Call "Optional#isPresent()" before accessing the value
这个看起来就很简单了,就是在使用这个value之前呢先得用Optional.isPresent()检查一下这个值是否为空
错误示范:
Optional<String> value = this.getOptionalValue();
// ...
String stringValue = value.get(); // Noncompliant
正确示范:
Optional<String> value = this.getOptionalValue();
// ...
if (value.isPresent()) {
String stringValue = value.get();
}
或者:
Optional<String> value = this.getOptionalValue();
// ...
String stringValue = value.orElse("default");
Invoke method(s) only conditionally
这个肯定是日子用的有问题咯,看看错误示范
logger.log(Level.DEBUG, "Something went wrong: " message);
logger.fine("An exception occurred with message: " message);
LOG.error("Unable to open file " csvPath, e);
正确示范:
logger.log(Level.SEVERE, "Something went wrong: {0} ", message);
logger.fine("An exception occurred with message: {}", message);
logger.log(Level.SEVERE, () -> "Something went wrong: " message);
LOG.error("Unable to open file {0}", csvPath, e);
if (LOG.isDebugEnabled() {
LOG.debug("Unable to open file " csvPath, e);
}
String contains no format specifiers
这个肯定是字符串格式化有问题或者不规范,比如
} catch (Exception er) {
logger.error("save error info failed", er.getLocalizedMessage());
}
String.format("First {0} and then {1}", "foo", "bar");
String.format("Display %3$d and then %d", 1, 2, 3);
String.format("Too many arguments %d and %d", 1, 2, 3);
String.format("First Line\n");
String.format("Is myObject null ? %b", myObject);
String.format("value is " value);
String s = String.format("string without arguments");
MessageFormat.format("Result '{0}'.", value);
MessageFormat.format("Result {0}.", value, value);
MessageFormat.format("Result {0}.", myObject.toString());
正确示范:
String.format("First %s and then %s", "foo", "bar");
String.format("Display %2$d and then %d", 1, 3);
String.format("Too many arguments %d %d", 1, 2);
String.format("First Line%n");
String.format("Is myObject null ? %b", myObject == null);
String.format("value is %d", value);
String s = "string without arguments";
MessageFormat.format("Result {0}.", value);
MessageFormat.format("Result '{0}' = {0}", value);
MessageFormat.format("Result {0}.", myObject);
Refactor this method to reduce its Cognitive Complexity from 32 to the 15 allowed
方法的复杂度过高,其实就是if太多了,方法的方法体太大了
减少if的判断,真的是业务比较复杂,将方法拆解,然后在规划出不满足条件的,直接return剩下的逻辑就都是满足的业务场景
Remove this unused "xxxx" private field
移除未使用的私有变量
No need to call "toString()" method as formatting and string conversion is done by the Formatter.
例如:
logger.info("地址余额信息:{}", addressBalanceMap.toString());
这里不需要调用tostring方法,应该调用自己需要看到的string format
This block of commented-out lines of code should be remoted
不用的代码块应该移除掉
Add a private consturctor to hide the implicit public one
添加一个私有构造函数来替代隐藏默认的共有的构造函数
错误示范:
class StringUtils
{
// Noncompliant
public static String concatenate(String s1, String s2) {
return s1 s2;
}
}
正确示范:
class StringUtils {
// Compliant
private StringUtils() {
throw new IllegalStateException("Utility class");
}
public static String concatenate(String s1, String s2) {
return s1 s2;
}
}
Change the visbility of this constructor to "protected"
这个一般是针对抽象类的,修改这个隐藏的默认的构造函数访问权限为protected
错误示范:
public abstract class AbstractClass1 {
public AbstractClass1 () {
// Noncompliant, has public modifier
// do something here
}
}
正确示范:
public abstract class AbstractClass2 {
protected AbstractClass2 () {
// do something here
}
}
Change this condition so that it does not always evaluate to "false"
修改条件,不能使用条件未执行的代码,例如:
a = false;
if (a) {
// Noncompliant
doSomething(); //这块永远都不会执行
// never executed
}
if (!a || b) {
// Noncompliant; "!a" is always "true", "b" is never evaluated
doSomething();
} else {
doSomethingElse(); //这块永远都不会执行
// never executed
}
Define and throw a dedicated exception instead of using a generic one
不应该抛出一个笼统的异常,应该定义一个自己的异常
错误示范:
public void foo(String bar) throws Throwable {
// Noncompliant
throw new RuntimeException("My Message"); // Noncompliant
}
正确示范:
public void foo(String bar) {
throw new MyOwnRuntimeException("My Message");
}
Add at least one assetion to this test case.
单元测试应该包含断言内容
错误示范:
@Test
public void testDoSomething() {
// Noncompliant
MyClass myClass = new MyClass();
myClass.doSomething();
}
正确示范:
@Test
public void testDoSomething() {
MyClass myClass = new MyClass();
assertNull(myClass.doSomething()); // JUnit assertion
assertThat(myClass.doSomething()).isNull(); // Fest assertion
}
Move constants defined in this interfaces to another class or enum.
接口中不应该定义一些常亮信息
例如:
interface Status {
// Noncompliant
int OPEN = 1;
int CLOSED = 2;
}
正确示范:
public enum Status {
// Compliant
OPEN, CLOSED;
}
或者:
public final class Status { // Compliant
public static final int OPEN = 1;
public static final int CLOSED = 2;
}
Add a nested comment explaining why this method is empty,thow an UnsupoorttedOperationException or complete the implementation
为什么会有个空方法,要么添加一些注释说明要么抛出UnsupportedOperationException
错误示范:
public void doSomething() { } 、
public void doSomethingElse() { }
正确示范:
@Override public void doSomething() {
// Do nothing because of X and Y.
}
@Override public void doSomethingElse() {
throw new UnsupportedOperationException();
}
Extract this nested try block into a separeate method.
try代码块不应该有嵌套
Return an empty collection instead null
返回一个空集合代替返回null
错误示范:
public static List<Result> getResults() {
return null; // Noncompliant
}
public static Result[] getResults() {
return null; // Noncompliant
}
正确示范:
public static List<Result> getResults() {
return Collections.emptyList(); // Compliant
}
public static Result[] getResults() {
return new Result[0];
}
Either log this exception and handler it,or rethrow it with some contextual information
log应该记录或重新抛出但不能同时记录跟抛出,说的有点绕,什么意思呢,大概看下错误实例代码就知道了
catch (SQLException e) {
...
LOGGER.log(Level.ERROR, contextInfo, e);
throw new MySQLException(contextInfo, e);
}
正确实例:
catch (SQLException e) {
...
throw new MySQLException(contextInfo, e);
}
或者:
catch (SQLException e) {
...
LOGGER.log(Level.ERROR, contextInfo, e);
// handle exception...
}
Either re-interrupt this method or rethrow the "InterruptedException"
不能忽略InterrupttedException这个异常
错误示范:
public void run () {
try {
while (true) {
// do stuff
}
}catch (InterruptedException e) {
// Noncompliant; logging is not enough
LOGGER.log(Level.WARN, "Interrupted!", e);
}
}
正确示范:
public void run () {
try {
while (true) {
// do stuff
}
}catch (InterruptedException e) {
LOGGER.log(Level.WARN, "Interrupted!", e); // Restore interrupted state...
Thread.currentThread().interrupt();
}
}
Use "BigDecimal.valueOf" instead
用BigDecimal.valueOf替代
错误示范:
double d = 1.1;
BigDecimal bd1 = new BigDecimal(d); // Noncompliant; see comment above
BigDecimal bd2 = new BigDecimal(1.1); // Noncompliant; same result
正确示范:
double d = 1.1;
BigDecimal bd1 = BigDecimal.valueOf(d);
BigDecimal bd2 = new BigDecimal("1.1");
Replace this "Map.get()" and condition with a call to "Map.computeIfAbsent()"
map.get 带条件的方法应该使用compuleIfAbsent,有就get没有就put
错误示范:
V value = map.get(key);
if (value == null) {
// Noncompliant
value = V.createFor(key);
if (value != null) {
map.put(key, value);
}
}
return value;
正确示范:
return map.computeIfAbsent(key, k -> V.createFor(k));
Add the missing @deprecated Javadoc tag
添加废弃注释时应该添加java注释,注释写清楚,让其他人知道什么情况废弃,废弃原因是什么
错误示范:
class MyClass {
@Deprecated
public void foo1() { }
/**
* @deprecated
*/
public void foo2() { // Noncompliant }
}
正确示范:
class MyClass {
/**
* @deprecated (when, why, refactoring advice...)
*/
@Deprecated
public void foo1() { }
/**
* Java >= 9
* @deprecated (when, why, refactoring advice...)
*/
@Deprecated(since="5.1") public void foo2() { }
/**
* Java >= 9
* @deprecated (when, why, refactoring advice...)
*/
@Deprecated(since="4.2", forRemoval=true)
public void foo3() { }
}
以上都是项目中扫描出来的不规范的代码,根据实际情况进行修改,标示出来的都是优先级比较高的,下次汇总会汇总一些优先级中等级别的出来以便记录
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com