sonar代码扫描常见问题以及处理方案
sonar代码扫描常见问题以及处理方案
最近用sonarqube对目前各系统的开发源码进行代码规则的扫描,发现了部分问题重复出现的频次还是很高的,借鉴网上的一些解决方案,整理记录一下。
一、异常处理中的未打印或者抛出异常信息
Either log or rethrow this exception.
这个主要是没有将异常信息打印出来,又或者异常没有抛出。比如我们在action中,异常信息是打印成日志,而service中是将异常信息抛出,按照这样做了,就不会再有这类的错误。
二、使用非同步的类来代替同步的类
Replace the synchronized class "StringBuffer" by an unsynchronized one such as "StringBuilder".
非同步的类在执行效率上会高于同步的类,所以在不是必须同步的情况下,建议使用非同步类。
处理方案:
ArrayList or LinkedList instead of Vector
Deque instead of Stack
HashMap instead of Hashtable
StringBuilder instead of StringBuffer
三、移除没有用到的包、变量、方法
Remove this useless assignment to local variable xxx
处理方案:移除无用的代码
四、增加有效注释,移除无用注释
This block of commented-out lines of code should be removed.
我们在开发中,需要增加有效注释,移除无用的无效注释。有时候,在修改代码的时候也会将以前的代码进行注释,防止下次修改的时候再拿来参考或者使用。这个也不推荐,因为时间长了,这类的僵尸代码也比较难清除,并且影响代码的阅读
处理方案:移除无用的注释
五、继承的方法需要添加@Override
Add the "@Override" annotation above this method signature
处理方案:在方法上方添加 @Override
六、嵌套不要超过三层
在写代码的时候,if/for/while/switch/try等代码的嵌套层数建议不要超过3层。当超过3层之后,代码的可读性和可维护性都会变的很差,同时如果做单元测试也会变的很艰难。
Refactor this code to not nest more than 3 if/for/while/switch/try statements.
错误示例
if (condition1) { // Compliant - depth = 1
/* ... */
if (condition2) { // Compliant - depth = 2
/* ... */
for(int i = 0; i < 10; i++) { // Compliant - depth = 3, not exceeding the limit
/* ... */
if (condition4) { // Noncompliant - depth = 4
if (condition5) { // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
/* ... */
}
return;
}
}
}
}
处理方案:减少嵌套层数
七、方法块的圈复杂度过高
The Cyclomatic Complexity of this method xxx is 11 which is greater than 10 authorized.
处理方案:减少嵌套,减少代码行数,避免一个方法过于冗长和沉重,提高阅读性和可维护性。
八、应合并可折叠的if语句
Merge this if statement with the enclosing one.
错误示例:
if (file != null) {
if (file.isFile() || file.isDirectory()) {
/* ... */
}
}
处理方案:
if (file != null && isFileOrDirectory(file)) {
/* ... */
}
private static boolean isFileOrDirectory(File file) {
return file.isFile() || file.isDirectory();
}
九、集合的是否为空集合的判断
Use isEmpty() to check whether the collection is empty or not.
在java的一些api中,提供了类似字符串、集合等常见对象的取值和判断的方法,我们要加以运用。
错误示例:
if (myCollection.size() == 0) { // Noncompliant
/* ... */
}
处理方案:
if (myCollection.isEmpty()) { // Compliant
/* ... */
}
十、整形/长整形转字符串的方法
Use "Long.toString" instead.
在java的一些api中,提供了类似字符串、集合等常见对象的取值和判断的方法,我们要加以运用。
错误示例:
int myInt = 4;
String myIntString = new Integer(myInt).toString(); // Noncompliant; creates & discards an Integer object
myIntString = Integer.valueOf(myInt).toString(); // Noncompliant
myIntString = 4 + ""; // Noncompliant
处理方案:
int myInt = 4;
String myIntString = Integer.toString(myInt);
十一、 BigDecimal的取值方法
Use "BigDecimal.valueOf" instead.
在java的一些api中,提供了类似字符串、集合等常见对象的取值和判断的方法,我们要加以运用。
错误示例:
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 = BigDecimal.valueOf(1.1);
十二、 使用新的变量来代替传入的变量
Use isEmpty() to check whether the collection is empty or not.
方法中传入的变量,一般情况下,我们认为是不可修改的,一旦可修改的话,在测试的时候不容易发现问题是调用方发生的错误还是方法本身发生的错误,这也是有的方法的传入参数为什么要定义为final类型的原因。
错误示例:
class MyClass {
public String name;
public MyClass(String name) {
name = name; // Noncompliant - useless identity assignment
}
public int add(int a, int b) {
a = a + b; // Noncompliant
/* additional logic */
return a; // Seems like the parameter is returned as is, what is the point?
}
public static void main(String[] args) {
MyClass foo = new MyClass();
int a = 40;
int b = 2;
foo.add(a, b); // Variable "a" will still hold 40 after this call
}
}
处理方案:
class MyClass {
public String name;
public MyClass(String name) {
this.name = name; // Compliant
}
public int add(int a, int b) {
return a + b; // Compliant
}
public static void main(String[] args) {
MyClass foo = new MyClass();
int a = 40;
int b = 2;
foo.add(a, b);
}
}}
十三、 使用正确的类型转换方法
Use "Integer.parseInt" for this string-to-int conversion
类型转换的方法有很多种方式,我们需要使用更合适的。
错误示例:
String myNum = "12.2";
float f = new Float(myNum).floatValue(); // Noncompliant; creates & discards a Float
处理方案:
String myNum = "12.2";
float f = Float.parseFloat(myNum);
十四、 不要使用System.out或者System.err
Replace this usage of System.out or System.err by a logger.
避免使用System.out和Sytem.err,而使用日志的方式输出,同时注意日志的级别,如果只是自己调试使用的话,不要使用Info以上的级别,使用debug就可以了。
错误示例:
System.out.println("My Message"); // Noncompliant
处理方案:
logger.info("My Message");
十五、 字符串比较的左边放常量,右边放变量
Move the "0" string literal on the left side of this string comparison.
错误示例:
String myString = null;
System.out.println("Equal? " + myString.equals("foo")); // Noncompliant - will raise a NPE
System.out.println("Equal? " + (myString != null && myString.equals("foo"))); // Noncompliant - null check could be removed
处理方案:
System.out.println("Equal?" + "foo".equals(myString)); // Compliant - properly deals with the null case