Sonar常见问题修改
作者:mmseoamin日期:2023-12-18

Sonar常见问题修改

    • 1 SonarLint简介与安装
      • 1.1 SonarLint简介
      • 1.2 SonarLint安装与配置
        • 1.2.1 IDEA 插件在线安装
        • 1.2.2 IDEA 插件离线安装
        • 1.2.3 SonarLint General配置(如果有规定的sonarQube)
        • 1.2.3 SonarLint Project配置
        • 2 SonarLint扫描以及IDEA中页面的名词解释
          • 2.1 SonarLint扫描
          • 2.2 IDEA中页面的名词解释
          • 3 主要问题
            • 1.String literals should not be duplicated
            • 2.Deprecated elements should have both the annotation and the Javadoc tag
            • 3.Generic exceptions should never be thrown
            • 4.Method names should comply with a naming convention
            • 5.Field names should comply with a naming convention
            • 6.Unnecessary imports should be removed
            • 7.Unnecessary imports should be removed
            • 8.Raw types should not be used
            • 9.Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used
            • 10."StandardCharsets" constants should be preferred
            • 11.Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used
            • 12.Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used
            • 13.Local variables should not be declared and then immediately returned or thrown
            • 14.Utility classes should not have public constructors
            • 15.Methods should not have too many parameters
            • 16.Nested blocks of code should not be left empty
            • 17.Modifiers should be declared in the correct order
            • 18."@Deprecated" code should not be used
            • 19.Track uses of "TODO" tags
            • 20.Strings and Boxed types should be compared using "equals()"
            • 21.Multiple variables should not be declared on the same line
            • 22."enum" fields should not be publicly mutable
            • 23."static" base class members should not be accessed via derived types
            • 24.The diamond operator ("<>") should be used
            • 25.Collection.isEmpty() should be used to test for emptiness
            • 26."switch" statements should have at least 3 "case" clauses
            • 27.Collapsible "if" statements should be merged
            • 28.Unused assignments should be removed
            • 29.Fields in a "Serializable" class should either be transient or serializable
            • 30."String#replace" should be preferred to "String#replaceAll"
            • 31.Methods should not be empty
            • 32.Unused "private" methods should be removed
            • 33.Standard outputs should not be used directly to log anything
            • 34.Empty arrays and collections should be returned instead of null
            • 35.Standard outputs should not be used directly to log anything
            • 36.Null pointers should not be dereferenced
            • 37.Package declaration should match source file directory
            • 38.Empty arrays and collections should be returned instead of null
            • 38."@Override" should be used on overriding and implementing methods
            • 39.Cognitive Complexity of methods should not be too hig
            • 40.XML parsers should not be vulnerable to XXE attacks
            • 4 参考文章
              • Sonar代码规则之TOP30详解
              • 在IDEA上配置SonarLint以及代码质量分析报告模板
              • @SneakyThrows注解
              • Sonar问题汇总
              • https://rules.sonarsource.com/

                1 SonarLint简介与安装

                1.1 SonarLint简介

                SonarLint是一个IDE插件,可帮助开发人员在编写代码时检测和修复质量问题。就像拼写检查器一样,SonarLint也会在提交代码之前对错误进行修正。开发人员可以直接从IDE市场获得它,然后它将在编码时(Java、JavaScript、PHP、Python和HTML)检测新的bug和质量问题。## 严重程度

                1.2 SonarLint安装与配置

                1.2.1 IDEA 插件在线安装

                File->Setting->Plugins 搜索SonarLint ->install

                Sonar常见问题修改,在这里插入图片描述,第1张

                1.2.2 IDEA 插件离线安装

                打开IDEA官方插件网站:

                http://plugins.jetbrains.com/idea

                搜索想要安装的插件,比如本文要安装的插件 SonarLint,在下面提示的下拉备选中,选择SonarLint跳转到插件页面.

                Sonar常见问题修改,在这里插入图片描述,第2张

                在插件页面下面找到历史版本(Version History),找到想使用的版本,点击downLoad等待下载完成.

                Sonar常见问题修改,[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PLNOcClu-1682322445764)(../assets/monthly/20230425/3.png)],第3张

                安装插件包

                Sonar常见问题修改,[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vsGFTfr-1682322445764)(../assets/monthly/20230425/4.png)],第4张

                1.2.3 SonarLint General配置(如果有规定的sonarQube)

                插件安装成功以后,打开插件配置界面,路径:File–Setting-Tools-SonarLint

                Sonar常见问题修改,[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3oPWOX2c-1682322445764)(../assets/monthly/20230425/5.png)],第5张

                弹窗窗口里,填写这个SonarLint的名称,我们使用的是本地sonarQube,选择的右边配置,输入sonarQube

                IP和端口号.完成后点击Next.

                Sonar常见问题修改,[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tRTGUpWr-1682322445764)(../assets/monthly/20230425/6.png)],第6张

                设置认证方式,有Token和用户名密码两种方式,根据自己的情况选择对应方式进行配置.

                Sonar常见问题修改,[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-egeFiLan-1682322445765)(../assets/monthly/20230425/7.png)],第7张

                1.2.3 SonarLint Project配置
                1. 选择下图中SonarLint Project Settings的菜单
                2. 勾选Bind project to SonarQube/SonarCloud
                3. 在Connection 右边下拉选择刚才配置的 sonar配置名称
                4. 配置Project key,可以点击Search in List,再弹出框里找到想使用的某个规则选择想使用的即可.
                5. 点击Apply使得配置生效保存

                  Sonar常见问题修改,[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LT8XQRcp-1682322445765)(../assets/monthly/20230425/8.png)],第8张

                2 SonarLint扫描以及IDEA中页面的名词解释

                2.1 SonarLint扫描

                在需要扫描的文件或者文件夹右击->SonarLint->Analyze with SonarLint

                Sonar常见问题修改,[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9T8gydb8-1682322445765)(../assets/monthly/20230425/9.png)],第9张

                2.2 IDEA中页面的名词解释

                Current file:当前文件(展示当前文件存在的哪些问题,以及解决方法)

                Rule:规则(告诉你问题的具体内容,并在最后告诉你如何解决这个问题)

                Report:报告(鼠标移动到项目根目录,右键选择Ayalyze,选择Ayalyze with SonarLint,完成之后的结果显示,包含整个项目的所有文件的问题)

                Locations:位置(告诉你,在哪个地方有问题,问题的重复位置)

                Issues:问题 每个issue有五种等级

                BLOCKER(致命):会影响应用程序的缺陷:内存泄漏,未关闭的JDBC连接…必须立刻修复的代码;

                CRITICAL(关键):可能会影响应用程序的缺陷或者是安全性缺陷:空的catch块,sql注入,…必须立刻查看代码;

                MAJOR(主要):可能会影响开发者效率的质量缺陷:未覆盖的代码,重复块,未使用的参数….

                MINOR(微小):可能会影响开发者效率的质量缺陷:每行不能太长,“switch”语句应该至少有三个条件….

                INFO(未知):既不是缺陷也不是质量问题,只是一个发现。

                每个issue有三个状态

                • Bug:窃听器(可靠性),避免错误和未定义的行为
                • Vulnerability:漏洞(安全),避免破坏或攻击 Code
                • Smell:代码嗅觉(可维护性),简化代码更新,并提高开发人员的速度

                  3 主要问题

                  1.String literals should not be duplicated

                  字符串文字不应该重复

                  代码中多次出现同一个字符串

                  应该将重复字符串抽取为常量

                  public static final String

                  2.Deprecated elements should have both the annotation and the Javadoc tag

                  弃用的元素应该同时具有注释和Javadoc标记

                  在标记弃用的元素 应该同时使用注释和Javadoc标记

                  Sonar常见问题修改,在这里插入图片描述,第10张

                  3.Generic exceptions should never be thrown

                  永远不应该抛出泛型异常

                  通用异常不应抛出 例如 Error Exception Throwable RuntimeException,修改为具体的或者自定义异常

                  在处理异常时,如果不往上抛的话,可以使用@SneakyThrows (编译后生成try catch)在本层处理。

                  4.Method names should comply with a naming convention

                  方法名应该遵循命名约定

                  方法应该按照规范命名

                  5.Field names should comply with a naming convention

                  字段名应该遵循命名约定

                  字段名应该遵循命名约定

                  6.Unnecessary imports should be removed

                  应该删除不必要的引用

                  应该删除不必要的引用

                  快捷键 ctrl + alt + o

                  7.Unnecessary imports should be removed

                  应该删除不必要的引用

                  应该删除不必要的引用

                  快捷键 ctrl + alt + o

                  8.Raw types should not be used

                  不应该使用原始类型

                  方法的返回值类型,参数的类型 应该明确 不应该使用泛型

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

                  不应该使用同步类Vector, Hashtable, Stack和StringBuffer

                  使用这些同步类虽然是线程安全的,但是比较影响性能

                  10.“StandardCharsets” constants should be preferred

                  “StandardCharsets”常量应该是首选

                  使用StandardCharsets.UTF_8 静态变量类型为charset 代替了HttpConstant.REQUEST_ENCODING这种静态变量类型为string的 符合java8规范

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

                  不应该使用同步类Vector, Hashtable, Stack和StringBuffer

                  使用这些同步类虽然是线程安全的,但是比较影响性能

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

                  不应该使用同步类Vector, Hashtable, Stack和StringBuffer

                  使用这些同步类虽然是线程安全的,但是比较影响性能

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

                  局部变量不应该声明后立即返回或抛出

                  本地变量如果赋值之后直接return了,那就直接return本地变量的赋值语句。

                  14.Utility classes should not have public constructors

                  实用程序类不应该有公共构造函数

                  公用类的工具类不应该有公共的构造函数,公用的工具类是静态成员的集合,并不意味这要实例化,当工具类不定义构造函数,Java会自动向不定义构造函数的每个类添加公共的构造函数,和公用类不应该具有公共的构造函数冲突了,因此我们需要手动添加该公用工具类的构造函数。

                  /**
                   * @Classname AdentUtil
                   * @Description 中介工具类
                   * @Version 1.0.0
                   * @Date 2023/3/27 13:46
                   * @Created by admin
                   */
                  public class AdentDataTransferUtil {
                   
                      /**
                       * 构造下载报文
                       * @param adentResultFileGeneralRespDto
                       * @return
                       */
                      public static UniteAdentResultFileRespDto getUniteAdentResultFileRespDto(AdentResultFileGeneralRespDto adentResultFileGeneralRespDto) {
                          UniteAdentResultFileRespDto uniteAdentResultFileRespDto=null;
                          if (adentResultFileGeneralRespDto != null) {
                              uniteAdentResultFileRespDto=new UniteAdentResultFileRespDto();
                              uniteAdentResultFileRespDto.setFileUnid(adentResultFileGeneralRespDto.getUnid());
                              uniteAdentResultFileRespDto.setFileName(adentResultFileGeneralRespDto.getName());
                              uniteAdentResultFileRespDto.setDownlaodUrl(adentResultFileGeneralRespDto.getDownloadUrl());
                          }
                          return uniteAdentResultFileRespDto;
                      }
                      private AdentDataTransferUtil() {
                          throw new IllegalStateException("Utility class");
                      }
                  }
                  

                  15.Methods should not have too many parameters

                  方法不应该有太多参数

                  用Spring的@RequestMapping(以及相关的快捷注释,如@GetRequest)或@JsonCreator注释的方法可能有很多参数,封装是可能的。因此,这些方法将被忽略。

                  16.Nested blocks of code should not be left empty

                  嵌套的代码块不应该留空

                  删除嵌套的空的代码块

                  17.Modifiers should be declared in the correct order

                  修饰符应该以正确的顺序声明

                  18.“@Deprecated” code should not be used

                  不应该使用“@Deprecated”代码

                  不能使用 或者不建议使用 @Deprecated 修饰的代码

                  例:import org.springframework.util.StringUtils; 引入了spring的包,但是它的StringUtils。isEmpty()不被建议使用,改用其他的的包 比如 org.apache.commons.lang3.StringUtils

                  19.Track uses of “TODO” tags

                  跟踪“TODO”标签的使用

                  20.Strings and Boxed types should be compared using “equals()”

                  将与该对象进行相等比较的对象

                  if(entry.getCode()==condition){}

                  修改为if(entry.getCode() != null && entry.equals(condition)){}

                  21.Multiple variables should not be declared on the same line

                  不应该在同一行上声明多个变量

                  22.“enum” fields should not be publicly mutable

                  “enum”字段不应该是公共可变的

                  修改访问修饰符

                  23.“static” base class members should not be accessed via derived types

                  “静态”基类成员不应该通过派生类型访问

                  原代码:JSONArray licenseArr = JSONArray.parseArray(licenseData);

                  修改后 JSONArray licenseArr = JSON.parseArray(licenseData);

                  为了代码清晰起见,永远不要使用子类的名称访问父类的静态成员。这样做会造成混淆,并且可能会导致存在两个不同的静态成员的错觉。直接使用父类访问父类静态成员。

                  24.The diamond operator (“<>”) should be used

                  应该使用菱形操作符(“<>”)

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

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

                  应该使用Collection.isEmpty()来测试是否为空

                  26.“switch” statements should have at least 3 “case” clauses

                  “switch”语句应该至少有3个“case”子句

                  如果不够三个case字句,改为用if,else

                  27.Collapsible “if” statements should be merged

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

                  Noncompliant Code Example
                  if (file != null) {
                    if (file.isFile() || file.isDirectory()) {
                      /* ... */
                    }
                  }
                  Compliant Solution
                  if (file != null && isFileOrDirectory(file)) {
                    /* ... */
                  }
                  private static boolean isFileOrDirectory(File file) {
                    return file.isFile() || file.isDirectory();
                  }
                  

                  28.Unused assignments should be removed

                  未使用的作业应该被删除

                  当局部变量被赋值后,后续指令不会读取该值时,就会发生死存储。计算或检索一个值,然后重写或丢弃它,可能表明代码中存在严重错误。即使这不是一个错误,它最多也是一种资源浪费。因此,应使用所有计算值。

                  29.Fields in a “Serializable” class should either be transient or serializable

                  “Serializable”类中的字段应该是瞬态的或者是可序列化的

                  当一个类实现了序列化接口 Serializable,意味着他可以可以序列化和反序列,当这个类里面的属性B没有实现 序列化接口 Serializable,意味着B不能序列化和反序列化,那么也就是类中的属性B不能序列化,sonar会报错。

                  1.为这个类B实现序列化接口 implement serializable

                  2.在属性B前面加上 transient 关键字 — private transient B b;

                  transient 对于transient 修饰的成员变量,在类的实例对象的序列化处理过程中会被忽略。

                  30.“String#replace” should be preferred to “String#replaceAll”

                  “String#replace"应该优先于"String#replaceAll”

                  简单替换逻辑使用replace效能更高

                  31.Methods should not be empty

                  方法不应该为空

                  使填写方法注释或者私有化构造器

                  private Assert() {
                          throw new IllegalStateException("Assert class");
                      }
                  

                  32.Unused “private” methods should be removed

                  应该删除未使用的“私有”方法

                  33.Standard outputs should not be used directly to log anything

                  标准输出不应该直接用于记录任何内容

                  34.Empty arrays and collections should be returned instead of null

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

                  Noncompliant Code Example
                  public static List getAllResults() {
                    return null;                             // Noncompliant
                  }
                  public static Result[] getResults() {
                    return null;                             // Noncompliant
                  }
                  public static Map getValues() {
                    return null;                             // Noncompliant
                  }
                  public static void main(String[] args) {
                    Result[] results = getResults();
                    if (results != null) {                   // Nullity test required to prevent NPE
                      for (Result result: results) {
                        /* ... */
                      }
                    }
                    List allResults = getAllResults();
                    if (allResults != null) {                // Nullity test required to prevent NPE
                      for (Result result: allResults) {
                        /* ... */
                      }
                    }
                    Map values = getValues();
                    if (values != null) {                   // Nullity test required to prevent NPE
                      values.forEach((k, v) -> doSomething(k, v));
                    }
                  }
                  Compliant Solution
                  public static List getAllResults() {
                    return Collections.emptyList();          // Compliant
                  }
                  public static Result[] getResults() {
                    return new Result[0];                    // Compliant
                  }
                  public static Map getValues() {
                    return Collections.emptyMap();           // Compliant
                  }
                  public static void main(String[] args) {
                    for (Result result: getAllResults()) {
                      /* ... */
                    }
                    for (Result result: getResults()) {
                      /* ... */
                    }
                    getValues().forEach((k, v) -> doSomething(k, v));
                  }
                  

                  35.Standard outputs should not be used directly to log anything

                  标准输出不应该直接用于记录任何内容

                  36.Null pointers should not be dereferenced

                  空指针不应该被解引用

                  对该对象加非空判断 例如:Objects.requireNonNull(obj);

                  37.Package declaration should match source file directory

                  包声明应该与源文件目录匹配

                  删除所在的包引用,自动重新set包路径

                  38.Empty arrays and collections should be returned instead of null

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

                  返回一个new 对象就好了 或者参照示例

                  public static List getAllResults() {
                    return Collections.emptyList();          // Compliant
                  }
                  public static Result[] getResults() {
                    return new Result[0];                    // Compliant
                  }
                  public static Map getValues() {
                    return Collections.emptyMap();           // Compliant
                  }
                  public static void main(String[] args) {
                    for (Result result: getAllResults()) {
                      /* ... */
                    }
                    for (Result result: getResults()) {
                      /* ... */
                    }
                    getValues().forEach((k, v) -> doSomething(k, v));
                  }
                  

                  38.“@Override” should be used on overriding and implementing methods

                  “@Override”应该用于重写和实现方法

                  需要为被提示的方法加上@Override

                  39.Cognitive Complexity of methods should not be too hig

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

                  需要优化代码

                  40.XML parsers should not be vulnerable to XXE attacks

                  XML解析器不应该容易受到XXE攻击

                  4 参考文章

                  Sonar代码规则之TOP30详解

                  在IDEA上配置SonarLint以及代码质量分析报告模板

                  @SneakyThrows注解

                  Sonar问题汇总

                  https://rules.sonarsource.com/