• Sonar是什么?

Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量 通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测

Sonar可以从以下七个维度检测代码质量,而作为开发人员至少需要处理前5种代码质量问题

1. 不遵循代码标准 sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写

2. 潜在的缺陷 sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具检测出潜在的缺陷

3. 糟糕的复杂度分布 文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员难以理解它们 且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试

4. 重复 显然程序中包含大量复制粘贴的代码是质量低下的,sonar可以展示源码中重复严重的地方

5. 注释不足或者过多 没有注释将使代码可读性变差,特别是当不可避免地出现人员变动时,程序的可读性将大幅下降 而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷

6. 缺乏单元测试 sonar可以很方便地统计并展示单元测试覆盖率

7. 糟糕的设计  通过sonar可以找出循环,展示包与包、类与类之间相互依赖关系,可以检测自定义的架构规则 通过sonar可以管理第三方的jar包,可以利用LCOM4检测单个任务规则的应用情况, 检测耦合。

更多代码分析工具可以查看:常用 Java 静态代码分析工具的分析与比较 https://www.oschina.net/question/129540_23043

  • SonrLint 安装与使用

https://www.cnblogs.com/qiumingcheng/p/7253917.html

  • sonar 常见解决方案

1.

Parentheses should be removed from a single lambda input parameter when its type is inferred

在推断单个lambda输入参数的类型时,应将其移除

There are two possible syntaxes for a lambda having only one input parameter with an inferred type: with and without parentheses around that single parameter. The simpler syntax, without parentheses, is more compact and readable than the one with parentheses, and is therefore preferred.

lambda有两种可能的语法,一种只有一个具有推断类型的输入参数:在该单个参数周围有括号,另一种没有括号。不带括号的简单语法比带括号的更紧凑、更易读,因此是首选语法。

Compliant Solution(统一解决方案):

这里将 (t) 的括号去掉即可

2.

String literals should not be duplicated  字符串文本不应重复

Duplicated string literals make the process of refactoring error-prone, since you must be sure to update all occurrences.

On the other hand, constants can be referenced from many places, but only need to be updated in a single place.

重复的字符串文本使重构过程容易出错,因为必须确保更新所有出现的情况。

另一方面,常数可以从许多地方引用,但只需要在一个地方更新。

Compliant Solution(统一解决方案):

相同的文本在多个地方使用的时候,需要统一定义同一个公共的常量参数

3.

Lambdas should be replaced with method references (lambda应替换为方法引用)

Method/constructor references are more compact and readable than using lambdas, and are therefore preferred. Similarly, null checks can be replaced with references to the Objects::isNull and Objects::nonNull methods.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

方法/构造函数引用比使用lambda更紧凑和可读,因此是首选的。类似地,可以将空检查替换为对 Objects::isNull 和 Objects::nonNull  方法的引用。

请注意,当项目的sonar.java.source低于8时,此规则会自动禁用。

Compliant Solution(统一解决方案):

这里可以将 w -> w.getItemNumId() 改成 PosStyleSkuVO :: getItemNumId

4.

不应使用同步类vector、hashtable、stack和stringbuffer

Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used

不应使用Synchronized 类如: vector、hashtable、stack和stringbuffer

Early classes of the Java API, such as Vector, Hashtable and StringBuffer, were synchronized to make them thread-safe. Unfortunately, synchronization has a big negative impact on performance, even when using these collections from a single thread.

Java API的早期类,如vector、HasTabe和StringBuffer,被使用 synchronized 来使它们线程安全。但是不幸的是,同步对性能有很大的负面影响,即使在从单个线程使用这些集合时也是如此。

It is better to use their new unsynchronized replacements:(最好使用新的非同步替换)

使用ArrayList or LinkedList 来替代 Vector

使用Deque 来替代 Stack

使用HashMap 来替代 Hashtable

使用StringBuilder 来替代 StringBuffer

Compliant Solution(统一解决方案):

这里可以可以使用 StringBuilder 而不是StringBuffer

5.

Unused method parameters should be removed (应删除未使用的方法参数)

Unused parameters are misleading. Whatever the values passed to such parameters, the behavior will be the same.

未使用的参数具有误导性。无论传递给这些参数的值是什么,行为都是相同的。

Compliant Solution(统一解决方案):

这里可以建议去除掉没有必要的参数

6.

Lamdbas containing only one statement should not nest this statement in a block

仅包含一条语句的lamdba不应将此语句嵌套在块中

There are two ways to write lambdas that contain single statement, but one is definitely more compact and readable than the other.

有两种方法可以编写包含单个语句的lambda,但是一种方法绝对比另一种方法更紧凑和可读。

Compliant Solution(统一解决方案):

这里可以去除掉 {} 和后面的 ; 号

7.

Cognitive Complexity of methods should not be too high

方法的认知复杂性不应太高。

Cognitive Complexity is a measure of how hard the control flow of a method is to understand. Methods with high Cognitive Complexity will be difficult to maintain.

认知复杂性是衡量一种方法的控制流程理解难度的指标。认知复杂性高的方法难以别的开发人员去维护。

Compliant Solution(统一解决方案):

对应这种if-else 过多方法,我们主要目的是要消除 if-else ,每多一个 else 那么就会多一个逻辑分叉,代码的易读性会急速降低,这里收集总结了一些地址,需要的同学可以去看一下:

减少该死的 if else 嵌套
java如何消除繁琐的if else 语句?
如何无痛降低 if else 面条代码复杂度
用设计模式来代替臃肿的ifelse层层判断

8.

Map values should not be replaced unconditionally

不应无条件替换映射值

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

当为键或索引保存一个值,然后无条件地覆盖时,它是高度可疑的。这种替代品可能是错误的。

Compliant Solution(统一解决方案):

去除一个相同的key 的put

9.

Printf-style format strings should be used correctly

应正确使用printf样式的格式字符串

Because printf-style format strings are interpreted(编译解释) at runtime, rather than validated(使生效) by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf-style format strings to their arguments when calling the format(...) methods of java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, and java.io.PrintWriter classes and the printf(...) methods of java.io.PrintStream or java.io.PrintWriter classes.

因为 printf-style 格式字符串是在运行时编译解释的,而不是由编译时生效的,所以它们可能包含导致创建错误字符串的错误。当调用java.util.formatter、java.lang.string、java.io.printstream、messageformat和java.io.printwriter类的format(...)方法以及java.io.printstream或java.io.printwriter类的format(...)方法时,此规则静态地证实了 printf-style 的 字符串 和 其参数的相关性(这句话的说白了就是,string.format 方法的与其参数息息相关,参数和主体字符串关系具有一定的关系,不要乱来)

Noncompliant Code Example (不符合的规则示例):

  1. String.format("First {0} and then {1}", "foo", "bar"); //Noncompliant. Looks like there is a confusion with the use of {{java.text.MessageFormat}}, parameters "foo" and "bar" will be simply ignored here
  2. String.format("Display %3$d and then %d", 1, 2, 3); //Noncompliant; the second argument '2' is unused
  3. String.format("Too many arguments %d and %d", 1, 2, 3); //Noncompliant; the third argument '3' is unused
  4. String.format("First Line\n"); //Noncompliant; %n should be used in place of \n to produce the platform-specific line separator
  5. String.format("Is myObject null ? %b", myObject); //Noncompliant; when a non-boolean argument is formatted with %b, it prints true for any nonnull value, and false for null. Even if intended, this is misleading. It's better to directly inject the boolean value (myObject == null in this case)
  6. String.format("value is " + value); // Noncompliant
  7. String s = String.format("string without arguments"); // Noncompliant
  8. MessageFormat.format("Result '{0}'.", value); // Noncompliant; String contains no format specifiers. (quote are discarding format specifiers)
  9. MessageFormat.format("Result {0}.", value, value); // Noncompliant; 2nd argument is not used

10> MessageFormat.format("Result {0}.", myObject.toString()); // Noncompliant; no need to call toString() on objects

11> java.util.Logger logger;

logger.log(java.util.logging.Level.SEVERE, "Result {0}.", myObject.toString()); // Noncompliant; no need to call toString() on objects

  1. logger.log(java.util.logging.Level.SEVERE, "Result.", new Exception()); // compliant, parameter is an exception
  2. logger.log(java.util.logging.Level.SEVERE, "Result '{0}'", 14); // Noncompliant {{String contains no format specifiers.}}
  3. org.slf4j.Logger slf4jLog;

org.slf4j.Marker marker;

slf4jLog.debug(marker, "message {}");

slf4jLog.debug(marker, "message ", 1); // Noncompliant {{String contains no format specifiers.}}

Compliant Solution(统一解决方案):

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);

java.util.Logger logger;

logger.log(java.util.logging.Level.SEVERE,"Result{0}.",myObject);

logger.log(java.util.logging.Level.SEVERE,"Result{0}'",14);

org.slf4j.Logger slf4jLog;

org.slf4j.Marker marker;

slf4jLog.debug(marker, "message {}");

slf4jLog.debug(marker, "message {}", 1);

这里的异常是主体字符串标识符只有一个{},但是却有两个参数,这个是不符合规则的

10.

String function use should be optimized for single characters

字符串函数的使用应针对单个字符进行优化

An indexOf or lastIndexOf call with a single letter String can be made more performant by switching to a call with a char argument.

使用 char 类型的参数可以提高单字母字符串的indexof或lastindexof调用的性能。

Compliant Solution(统一解决方案):

将result.indexOf(".") 改成 result.indexOf('.')

11.

Empty arrays and collections should be returned instead of null

应返回空数组和集合,而不是 null

Returning null instead of an actual array or collection forces callers of the method to explicitly test for nullity, making them more complex and less readable.

Moreover, in many cases, null is used as a synonym for empty.

返回null来替代 实际的数组或集合 会强制是该方法的”调用方”很明确的去测试为null的情况,从而使它们更复杂,可读性更低。此外,在许多情况下,null 也用作 empty 的同义词;

Compliant Solution(统一解决方案):

这里将return null; 改为Collections.emptyList();

12.

Collapsible "if" statements should be merged

应该合并可折叠的“if”语句

Merging collapsible if statements increases the code's readability.

合并可折叠的if语句可以提高代码的可读性。

Compliant Solution(统一解决方案):

这里将:

else if(shop.getType() == 2) {

//过滤门店自定义无库存tab

if(!filterNoGoodsTabBySearch(shop)) {

continue;

}

}

改为

//过滤门店自定义无库存tab

else if(shop.getType() == 2 && !filterNoGoodsTabBySearch(shop)) { continue;

}

这里其实不改的话 可读性更高点,具体要不要修改要视实际情况而定!

13.

Dead stores should be removed

应移除废弃存储

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

当一个局部变量被分配一个值,而该值不被任何后续的指令读取时,就会发生死区。计算或检索一个值,然后覆盖或丢弃它,可能表示代码中存在严重错误。即使这不是一个错误,也充其量只是浪费资源。因此,应使用所有计算值。

Compliant Solution(统一解决方案):

这里将 Long[] memberIds =new Long[6];

List<Long> ids = this.getRecentShopCommentMember(shopId);

memberIds = new Long[ids.size()];

memberIds = ids.toArray(memberIds);

改为:    List<Long> ids = this.getRecentShopCommentMember(shopId);

Long[] memberIds =  new Long[ids.size()];

memberIds = ids.toArray(memberIds);

14.

Collection.isEmpty() should be used to test for emptiness

collection.isEmpty()应用于测试是否为空

Using Collection.size() to test for emptiness works, but using Collection.isEmpty() makes the code more readable and can be more performant. The time complexity of any isEmpty() method implementation should be O(1) whereas some implementations of size() can be O(n).

使用collection.size()测试空性是可行的,但是使用collection.isEmpty() 可以使代码更可读,更具性能。任何isEmpty() 方法实现的时间复杂性都应该是O(1),而某些size() 的实现可以是O(n)。

Compliant Solution(统一解决方案):

这里工具建议使用 collection 的 isEmpty() 方法,但是实际上 collection 是否为null ,这个也是我们需要判断的,所以我们可以使用 CollectionUtils.isNotEmpty()方法

Ps:

list.size()>0 :

list.size()>0这个方法会先计算一下list里元素的个数,然后再和0进行比较

list.isEmpty()

判断list里是否有元素,list不需要计算元素个数,直接看一下是否为空

即查size时间复杂度是o(n) ,如果是empty o(1);所以判断集合是否为空一般用list.isEmpty()来判断;

CollectionUtils.isEmpty() 正是如此

另外对于某些明显已经实例化的collection ,我们其实也不用全部调用CollectionUtils.isEmpty 方法,这样依然能够满足需求

15.

布尔类型的返回值不需要去判断布尔文本

16.

Local variables should not be declared and then immediately returned  or thrown

不应声明局部变量,然后立即返回或者抛出它

Declaring a variable only to immediately return or throw it is a bad practice(实践;练习;惯例;)

Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

只声明一个变量以立即返回或抛出它是一种糟糕的惯例。

一些开发人员认为该惯例提高了代码的可读性,因为它使他们能够显式地命名返回的内容。但是,该变量是一个内部实现细节,我们完全不需要向方法的调用方公开内部细节。而且方法名应该足以让调用方确切知道将返回什么。

Compliant Solution(统一解决方案):

将:

Set<String> list = redisService.zreverage(key,0,5);

return list;

改为:

return redisService.zreverage(key,0,5);

17.

The diamond operator ("<>") should be used

应使用菱形运算符(“<>”)

Java 7 introduced the diamond operator (<>) to reduce the verbosity of generics code. For instance, instead of having to declare a List's type in both its declaration and its constructor, you can now simplify the constructor declaration with <>, and the compiler will infer the type.

Java 7引入了菱形运算符(<>)来减少泛型代码的冗长性。例如,不必在列表的声明和构造函数中同时声明列表的类型,现在可以用<>简化构造函数声明,编译器将推断该类型。

Compliant Solution(统一解决方案):

List<Long> ids = new ArrayList<>();

18.

The diamond operator ("<>") should be used

应使用菱形运算符(“<>”)

Java 7 introduced the diamond operator (<>) to reduce the verbosity of generics code. For instance, instead of having to declare a List's type in both its declaration and its constructor, you can now simplify the constructor declaration with <>, and the compiler will infer the type.

Java 7引入了菱形运算符(<>)来减少泛型代码的冗长性。例如,不必在列表的声明和构造函数中同时声明列表的类型,现在可以用<>简化构造函数声明,编译器将推断该类型。

Compliant Solution(统一解决方案):

List<Long> ids = new ArrayList<>();

19.

用Arrays.asList() 方法得到的List的长度是不可改变的,

当你向这个List添加或删除一个元素时(例如 list.add("d");)程序就会抛出异常:

Arrays.asList()源码如下

@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {return new ArrayList<>(a);
}

这里需要注意这个new ArrayList<>(a)

这个ArrayList不是java.util包下的,而是java.util.Arrays.ArrayList

它是Arrays类自己定义的一个静态内部类,这个内部类没有实现add()、remove()方法,而是直接使用它的父类AbstractList的相应方法,对应的set add remove 方法如下:

public E set(int index, E element) {throw new UnsupportedOperationException();
}
public void add(int index, E element) {throw new UnsupportedOperationException();
}
public E remove(int index) {throw new UnsupportedOperationException();
}

所以如果后续需要对该参数进行添加移除等操作的时候,就不要使用Arrays.asList() 了 ,老老实实用Lists.newArrayList()吧。

20.

"BigDecimal(double)" should not be used

不应使用“BigDecimal(double)”。

Because of floating point imprecision, you're unlikely to get the value you expect from the BigDecimal(double) constructor.

由于浮点不精确,您不太可能从bigdecimal(double)构造函数获得预期的值。

javase/7/docs

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

这个构造函数的结果可能有些不可预测。人们可以假设在Java中创建一个新的BigDeCimple(0.1)创建一个完全等于0.1的BigDecimal(一个未缩放的值为1,具有1的规模),但实际上它等于0.100000 000 000 000 555 1112312757 827 0211815834045 41015625。这是因为0.1不能精确地表示为一个双精度数(double)(或者就此而言,不能精确地表示为任何有限长度的二分之一)。因此,虽然看起来外观如此都是0.1,但是实际上传递给构造函数的值并不完全等于0.1。

PS: 目前收集和整理了大概这些,后续还会不定期补充,这里为什么依然使用英文不用汉化版的插件,这里就不解释了,部分翻译是我根据自己的理解自己补充的,大家看看理解就行,不必太在意这个!

整理不易,如果对你有帮助记得留个赞再走呀!!

SonrLint常见解决方案相关推荐

  1. 【分布式篇】什么是分布式ID?分布式ID常见解决方案有哪些?

    目录 分布式ID 什么是分布式ID 分布式ID需要满足的需求 基本需求: 其他需求 分布式 ID 常见解决方案 1. 数据库维度 基于数据库主键自增实现 优点 : 缺点 : 基于数据库的号段模式实现( ...

  2. 跨域(CORS)请求问题[No 'Access-Control-Allow-Origin' header is present on the requested resource]常见解决方案

    基本概念 跨域(CORS)请求:同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略, ...

  3. 一致 先验分布 后验分布_分布式事务常见解决方案与最终一致性

    小编推荐:互联网大背景下,微服务盛行,平时开发中难免会遇到分布式事务问题.大家经常会听到CAP原理,即一致性(Consistency).可用性(Availability).分区容错性(Partitio ...

  4. Android应用漏洞及常见解决方案

    文章目录 一. 基本信息 1.1 应用权限 1.2 应用行为 1.3 第三方SDK 1.4 恶意程序 1.5 越权行为 1.6 权限滥用风险 1.7 资源文件包含APK 二. 源文件安全 2.1 应用 ...

  5. 推荐系统冷启动问题的常见解决方案

    本文在<推荐系统实践>(项亮)一书的基础上介绍一下推荐系统的冷启动问题. 1.冷启动问题定义 推荐系统需要根据用户的历史行为和兴趣预测用户未来的行为和兴趣,对于BAT这类大公司来说,它们已 ...

  6. 分布式ID常见解决方案总结

    一.数据库 1.数据库主键自增 这种方式就比较简单直白了,就是通过关系型数据库的自增主键产生来唯一的 ID. 以 MySQL 举例,我们通过下面的方式即可. 1.1.创建一个数据库表. CREATE ...

  7. 单点登录(一)—— 单点登录及常见解决方案原理(CAS、oauth2、JWT)

    背景 在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,用户用不同的账号即可登录,很方便. 但随着企业的发展,用到的系统随之增多,用户在操作不同的系统时,需要多次登录, ...

  8. USB转串口 DM9625IS / PL2303 / FT232 CH340常见解决方案介绍与比较

    我们手边的台式机或笔记本几乎没有带串口了,而串口又是做项目开发一定会用到的通讯接口之一,由于USB接口的普及,在利用USB转串口就比较方便多了,市场上常见的USB转串口芯片有DM9625IS .FT2 ...

  9. 图文剖析:单点登录常见解决方案实现原理

    作者:一叶知秋 https://muyinchen.github.io/ 一.共享Session 二.基于OpenId的单点登录 三.基于Cookie的OpenId存储方案 四.B/S多域名环境下的单 ...

最新文章

  1. sql自动生成工具_可自动生成代码,5款基于AI的开发工具
  2. Coding中遇到的BUG集合~
  3. Notepad++插件之ftp/sftp远程编辑功能,以及各种插件(转:http://blog.csdn.net/happy_wu/article/details/73302994)
  4. 腾讯云linux系统结合nginx部署项目
  5. 服务器tomcat配置教程
  6. 指针04 - 零基础入门学习C语言44
  7. html插入图片出现红叉,网页图片显示红色叉怎么回事 网页图片有些不显示的有效解决方法...
  8. Linux系统C/C++通用错误码实现模板
  9. [编写高质量代码:改善java程序的151个建议]建议43 避免对象浅拷贝; 建议44:推荐使用序列化实现对象的深拷贝...
  10. 基于Nonebot2搭建QQ机器人实战篇(一)
  11. 用户如何制作360度全景图?360度全景图有什么用?
  12. perfect forward secrecy
  13. 助教日志_【沈阳航空航天大学软件工程 1,2 班】前六周排行榜
  14. 世界在变化刷脸支付一直奋进
  15. PAKDD 2019 AutoML 挑战赛圆满落幕,中国队伍包揽前三...
  16. 【C】C课程设计-驾校考试模拟系统
  17. 美光消费级3D SSD:最大2TB
  18. 多项式函数在某一点处的泰勒展开
  19. get(obj, “a.b[0].c“, 0)
  20. Object Detection经典代码与文章

热门文章

  1. 防火墙单向访问控制_使用防火墙实现安全的访问控制
  2. 删除二叉树节点完整c语言程序以及例子,C语言C++实现二叉树构造与查找删除节点.doc...
  3. 通孔焊盘命名规范-002
  4. 学会这两招将知网下载的CAJ转成Word形式
  5. 儿童使用显微镜有好处吗?
  6. MacM1下使用opencv
  7. 记一次windows 10 无法升级问题的处理(系统盘MBR转GPT)
  8. 仪表放大器和运算放大器优缺点对比
  9. iOS应用程序内存泄露的监测
  10. 音符起始点检测(音频节奏检测)(4.5)