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 { // 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

    分享
    投诉
    首页