接下来我们就一起去研究一下吧!sonar指导手册阿里巴巴开发规范及sonar相信很多人都用过,今天主要汇总一下,用sonar扫描出来的一些代码问题。在开发中,经常一顿猛如虎的操作下来,代码是码完了,单元测试貌似也测了,代码的覆盖率好像也都覆盖了,结果符合预期,貌似可以提测了。这时有点方,好吧先不提测了,先看看sonar扫了些什么出来。

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 {// Compliantprivate 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 { // Noncompliantpublic static String concatenate(String s1, String s2) {return s1s2;}}
正确示范:
class StringUtils { // Compliantprivate StringUtils() {throw new IllegalStateException("Utility class");}public static String concatenate(String s1, String s2) {return s1s2;}}
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) { // NoncompliantdoSomething(); //这块永远都不会执行// never executed}if (!a || b) { // Noncompliant; "!a" is always "true", "b" is never evaluateddoSomething();} else {doSomethingElse();//这块永远都不会执行// never executed}
Define and throw a dedicated exception instead of using a generic one
不应该抛出一个笼统的异常,应该定义一个自己的异常
错误示范:
public void foo(String bar) throws Throwable { // Noncompliantthrow new RuntimeException("My Message"); // Noncompliant}
正确示范:
public void foo(String bar) {throw new MyOwnRuntimeException("My Message");}
Add at least one assetion to this test case.
单元测试应该包含断言内容
错误示范:
@Testpublic void testDoSomething() { // NoncompliantMyClass myClass = new MyClass();myClass.doSomething();}
正确示范:
@Testpublic void testDoSomething() {MyClass myClass = new MyClass();assertNull(myClass.doSomething()); // JUnit assertionassertThat(myClass.doSomething()).isNull(); // Fest assertion}
Move constants defined in this interfaces to another class or enum.
接口中不应该定义一些常亮信息
例如:
interface Status { // Noncompliantint OPEN = 1;int CLOSED = 2;}
正确示范:
public enum Status { // CompliantOPEN,CLOSED;}
或者:
public final class Status { // Compliantpublic 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() {}
正确示范:
@Overridepublic void doSomething() {// Do nothing because of X and Y.}@Overridepublic 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 enoughLOGGER.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 aboveBigDecimal 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) { // Noncompliantvalue = 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 {@Deprecatedpublic void foo1() {}/*** @deprecated*/public void foo2() { // Noncompliant}}
正确示范:
class MyClass {/*** @deprecated (when, why, refactoring advice...)*/@Deprecatedpublic 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() {}}
以上都是项目中扫描出来的不规范的代码,根据实际情况进行修改,标示出来的都是优先级比较高的,下次汇总会汇总一些优先级中等级别的出来以便记录
