【转】Sonar扫描bug修复

1.Not enough arguments.

在这里插入图片描述
上面的这种bug在项目中很常见,参数都用new Object[]{}封装起来。特别是从class文件反编译回来成的java文件格式也是这样的。但是如果要消除bug的话直接使用参数就好了,不要用new Object[]{}封装。
在这里插入图片描述

2.This branch can not be reached because the condition duplicates a previous condition in the same sequence of “if/else if” statements

if分支中不能出现两个分支一样的情况。
在这里插入图片描述

把重复的删除掉就可以了。

3.Use try-with-resources or close this “FileInputStream” in a “finally” clause.

在这里插入图片描述

提示资源没有关闭,需要在finally中进行资源关闭,但是把资源关闭放到finally中由提示这样写不规范有异味。所以它推荐的写法是将创建资源流的代码放在try()中,这样系统会自动的关闭资源,不需要我们写.close()方法,如图
在这里插入图片描述

4.A “NullPointerException” could be thrown; “document” is nullable here.

在这里插入图片描述
这种提示是指可能存在空指针异常,需要增加空值检测。
在这里插入图片描述

5.Cast one of the operands of this addition operation to a “double”.

在这里插入图片描述
这里提示的是在进行操作运算之前应该先进行类型转换。下面是他提供的一些规范和不规范的实例。
在这里插入图片描述

可以看出来,基本上是给提示的参数进行强类型转换,怎么知道应该转换什么类型呢,可以点击对应的方法查看这个参数是什么类型的,就将这个参数强转成这个类型就好了,比如上面的doubleTostring()方法的第二个参数是double类型的,所以强转一下就好了,如下:
在这里插入图片描述

6.emove or correct this useless self-assignment.

在这里插入图片描述
提示是删除或纠正这种无用的自我分配。一看上面的代码,因该是哪位大佬写错了吧,所以改成temp2[i]=temp1[i];也算消除了异味

7.Save and re-use this “Random”.
在这里插入图片描述
这种提示是随机数应该需要重用,然后他给出的参考是这样的
在这里插入图片描述
在类中定义一个Random,然后在方法中可以重复使用,但是我按照这个方法试了一下没发现并不可行,导入下面的两个包都会报错,应该是需要什么额外的jar包才行感觉。
在这里插入图片描述
所以做了一个消除bug的方法。如下图,其实感觉变复杂了哈哈,但是消除了bug
在这里插入图片描述

8.Use an “instanceof” comparison instead.

在这里插入图片描述
上面代码都是报这个bug,提示不应该按照名称来比较类。
不要求类名是唯一的,只要它们在包中是唯一的。 因此,尝试根据类名确定对象的类型是一种充满危险的练习。 其中一个危险是恶意用户将发送与受信任类同名的对象,从而获得可信访问。
相反,应该使用instanceof运算符或Class.isAssignableFrom()方法来检查对象的基础类型。
下面我是通过isAssignableFrom()来消除bug的。如下图:
在这里插入图片描述

9.Prevent “int” promotion by adding “& 0xff” to this expression.

在这里插入图片描述
提示原始字节值不应与逐位运算结合使用,读取字节以构建其他原始值(如整数或长整数)时,将自动提升字节值,但该提升可能会产生意外结果。要防止此类意外值转换,请使用按位和(&)将字节值与0xff(255)组合,然后关闭所有较高位。所以在后面就加上“&0xff”如图:

在这里插入图片描述

10.Make “df” an instance variable

在这里插入图片描述
提示非线程安全字段不应该是静态的,所以把前面的static 修饰符去掉就可以。

11.Either re-interrupt this method or rethrow the “InterruptedException”

在这里插入图片描述
这种interrupt异常,需要在catch中加上Thread.currentThread().interrupt();

在这里插入图片描述

12.Remove the unboxing from “Integer”

在这里插入图片描述
提示是这个Integer封装是多余的,所以直接用强类型转换就可以吧。
在这里插入图片描述

13.Use another way to initialize this instance

在这里插入图片描述
这个提示用其他的方式初始化,不要在定义的时候就初始化,修改如下:
在这里插入图片描述

遇到的基本上就是这些bug了,还有css中的一些bug,按照提示修改的

14.Unexpected missing generic font family

在这里插入图片描述
将这两个body的样式合二为一,可以消除bug和漏洞

15.Unexpected duplicate “display”

在这里插入图片描述
Display 重复了,删除掉一个。

16.Unexpected unknown type selector “element”

在这里插入图片描述
空样式,直接删除掉。

17. Change this condition so that it does not always evaluate to “false”

(更改此条件,以便它不总是评估为“false")
这是很多webservice文件中出现的一个bug。 如果后期会对webservice文件过滤,这个就可以不管了。不过也可以把这行删除掉,obj不可能为null if (obj == null) return false; 这样这个bug也没有了。
在这里插入图片描述

18.Make “XXX” an instance variable.

说明:有些类不是线程安全的,将变量生命为静态的可能会导致线程安全问题
解决方案:将变量声明为实例的。

 

19.Either re-interrupt this method or rethrow the “InterruptedException”

这种interrupt异常,需要在catch中加上Thread.currentThread().interrupt();

二 漏洞

1.Use a logger to log this exception

在这里插入图片描述
这种提示就是异常应该用日志打印出来。
在这里插入图片描述

2.‘password’ detected in this expression, review this potentially hard-coded credential

在这里插入图片描述
提示密码不能直接这样传递,不安全。但是也没有提供参考的案例。所以我是这样的改的,也能消除漏洞。如下图:
在这里插入图片描述

3.Make areaList a static final constant or non-public and provide accessors if needed

在这里插入图片描述
类变量字段不应具有公共可访问性。所以把public访问修饰符,改成其他的修饰符,最好是private.
在这里插入图片描述

4.Secure this “Transformer” by either disabling external DTDs or enabling secure processing.

在这里插入图片描述
提示应该保护XML变换器。创建javax.xml.transform.Transformer但未启用“安全处理”或创建一个而不禁用外部DTD时,可能会发生XML外部实体或XSLT外部实体(XXE)漏洞。 如果该外部实体被攻击者劫持,则可能导致机密数据泄露,拒绝服务,服务器端请求伪造,从解析器所在机器的角度进行端口扫描,以及其他系统影响。
进行修改如下可以消除漏洞:
在这里插入图片描述

5.Do something with the “boolean” value returned by “delete”.

在这里插入图片描述
提示当包含操作状态代码时,不应忽略返回值。也就是说不应该忽略文件删除操作的结果。
所以进行如下修改,但是如下修改虽然修复了漏洞,但是新增了异味。
在这里插入图片描述
异味提示"java.nio.Files#delete" should be preferred (squid:S4042)。应该使用Files.delete()方法,而不能之间文件delete.所以最后修改成:
在这里插入图片描述

6.Make this “public static userInfoUrl” field final

在这里插入图片描述
这种“public static”字段应该成员变量应该是不变的,所以需要加上final修饰,如下:
在这里插入图片描述

还有几种漏洞不好修复,暂时没有思路

7.Change this method so it throws exceptions

在这里插入图片描述
这种提示,TrustManagers不应盲目接受任何证书。通常会创建X509TrustManager接口的空实现,以允许连接到未由根证书颁发机构签名的主机。 这样的实现将接受任何证书,这使得应用程序容易受到中间人攻击。 正确的解决方案是提供适当的信任存储。

8.Use the recommended AES (Advanced Encryption Standard) instead.

在这里插入图片描述

这种原来用DES加密的提示不应使用DES(数据加密标准)和DESede(3DES)。它推荐的使用AES.但是将DES加密改成AES加密虽然程序异味消除了,但是程序肯定不对吧,加密方式换了肯定会出问题的吧。

三 异味

异味太多了,我也没有消除太多了异味,一个项目异味一般都是好几k,所以消除起来一两个异味对基数没有什么影响,并且异味太多,消除一部分后,并没有感受到那种异味数量巨减的感觉,导致消除异味的积极性不是很高。并且有的异味是真的不好消除,有时候打开一个文件,几千行代码一片都是标异味。直接就放弃了。

1.Replace the type specification in this constructor call with the diamond operator ("<>").

在这里插入图片描述
Java 7引入了菱形运算符(<>)来减少泛型代码的冗长。 例如,您现在可以使用<>简化构造函数声明,而不必在其声明及其构造函数中声明List的类型,编译器将推断该类型。如下:
在这里插入图片描述

2.Add a default case to this switch

在这里插入图片描述
swatch 中没有default,也没有break;虽然上面的代码不要break也不会有什么问题。但是万一哪天变了,不是return 就很容易出错了吧。

3.Remove this empty statement.

在这里插入图片描述
两个分号,代码中有很多地方有这种情况感觉,删掉多余的。

4.Remove this useless assignment to local variable “XXX”.

在这里插入图片描述
上图,定义的变量但是没有使用,就会抛出这种异味,解决这种异味,是需要看看这个变量有什么作用,没有作用的可以删除掉,如果不改随意改动,可以在他们下面增加一条日志打印他们,这样也能消除这个异味。

5.Directly append the argument of String.valueOf().

在这里插入图片描述
String.valueOf()不应附加到String。这里我的理解是,result是string类型,arerType是int类型,在拼接的时候会自动的将int类型转换成string,不用多此一举。

在这里插入图片描述

6.Define a constant instead of duplicating this literal “XXXX” 4 times.

在这里插入图片描述
类似这种,当一个不变的字符串在一个文件中多次出现,就应该给这些字符串提取成常量,这样方便以后修改和维护。但是说实话提取常量这个异味真的很枯燥,并且代码中有大量的这种情况,感觉每个项目或者每个模块都应该提取一个常量类,这样这个模块用到这些不变字符串,就直接从这个类中获取,但是这个工作量有点大哈哈,我就简单的尝试了一下,把自定义报表那部分提取常量,但是进行了一部分就没有进行下去了,枯燥且工作量大
在这里插入图片描述
在这里插入图片描述

但是我觉得这个工作还是做比较好,这样便于以后的维护,常量值改变只用改一个地方就好了,不用所有地方都修改。

7.Use a StringBuilder instead.

在这里插入图片描述
当字符串需要频繁变化时,用stringBuilder代替string .这里还有一种异味是代码中有的地方用的是StringBuffer,也需要转成StringBuilder.因为Stringbuffer是确保线程安全的,stringBuilder
不用,所以stringBuilder效率更高。那会不会引发线程安全问题呢,不会,因为这个是在方法内部定义的变量,所以对这个方法而言是线程封闭的,不会引发线程安全问题。

8.Reorder the modifiers to comply with the Java Language Specification.

在这里插入图片描述
提示修饰符的顺序应该符合java语言规范,它给出的参考如下:
在这里插入图片描述
所以把static修饰符 放到final就好了。

9.Declare “XXX” on a separate line.

在这里插入图片描述
定义变量的时候,一个变量一行,便于查看

在这里插入图片描述

10.Return an empty collection instead of null.

在这里插入图片描述
最好不要直接返回null,应返回空数组和集合.如下:
在这里插入图片描述

11.Use isEmpty() to check whether the collection is empty or not.

在这里插入图片描述
判断集合时候为空是,不要使用size(),建议使用isEmpty()方法。如下:

在这里插入图片描述

12.This block of commented-out lines of code should be removed

在这里插入图片描述
这种可以直接删除掉,或者不想删除的可以用/***/注释,对于单行的可以把后面的分号去掉就不会报错异味了。
在这里插入图片描述

13.Remove the literal “false” boolean value

在这里插入图片描述
布尔文字不应该是多余的。用true或者false在if中判断是不好的写好,直接可以通过本身进行判断,如下:
在这里插入图片描述

14.Add a private constructor to hide the implicit public one.

在这里插入图片描述
如果一个类的里面的方法都是static修饰的静态方法,那么需要给这个类定义一个非公共构造函数(添加私有构造函数以隐藏隐式公共构造函数)如下:

在这里插入图片描述

15.Refactor this method to reduce its Cognitive Complexity from 55 to the 15 allowed.

在这里插入图片描述
关于代码圈复杂度大于15的异味,以及代码过长的异味,说实话也没有什么好的方法,只能读代码,然后抽离函数出来,当然抽离函数不可能一次就能做到代码简洁之道要求的那样,一个函数只做一件事,单一层次原则。但是我们也不能因为做不到这样就就什么都不做,还是要迈出这一步,先抽离函数,虽然没有做到单一层次原则,但是消除了异味。下面代码是对上面的进行简单的函数抽离,消除异味
在这里插入图片描述

16.关于代码中很多的stitch分支问题。

在这里插入图片描述
在这里插入图片描述

这样代码上看去显得非常的臃肿且感觉特别low,但是这却是我们最喜欢写的包括我自己,因为简单进本不用思考。并且如下图,18个case都没有报异味,所以SonarQube上也没有检查出来,所以大家都将就先改其他,后来被数据端同事看到了下面这个代码,说代码简洁之道不是说不能用这么多的swatch么?我竟然一时不知道怎么回答,只能说修改成本太大,不好改。但是事后自己仔细想想自己接受这段代码看的也感觉特别low,那自己为什么不能对自己的要求高一点呢,所以痛定思痛打算改这段代码。

我修改这部分代码采用的是枚举类型,先创建一个枚举,并将所有的case换成对应的枚举值,然后创建两个成员变量和一个带两个参数的枚举的构造方法。然后实现这两个成员变量的get方法,使得其他类可以访问。如下图:
在这里插入图片描述
然后在原来的swatch的代码中,删除这些分支,创建这个枚举,并根据分支创建对应的枚举值,如下:

在这里插入图片描述
这样就完成啦,看起来总算比那么多的swatch-case舒服很多吧,并且也没有那么low了。

17.还有一些其他的异味消除。直接贴图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
两个分支一模一样的,需要删掉其中一个。然后像这种有很多if-else if的getsql()方法的圈复杂度肯定是超过了,这里比较好的方法我也不知道怎么做,但是我是将整个分成多个一样的if-else if的方法。但是这样只能消除异味,代码的可读性变差。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
条件语句如果是单行,需要使用缩进。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

18.还有一些不知道怎么清除的异味。

在这里插入图片描述
在这里插入图片描述
异味有很多,不会清除的异味也肯定不止这些,难清除和不会清除的异味可以先记录下来。先把容易的好清除的异味清除掉,应该也能达到标准吧,至于难清除的,以后可以一起讨论看看怎么清除。

 

附加

1.Equality tests should not be made with floating point value

  代码举例: if (result == num) //result和num均为double 之间比较会有精度损失

  解决:BigDecimal data1 = new BigDecimal(totalArea);

     BigDecimal data2 = new BigDecimal(s1);

        int num = data1.compareTo(data2);//num =0 相等  >0前者大于后者 ,反之 <0 前者小于后者

2.This class overrides "equals()" and should therefore also override "hashCode()". 

  代码举例:public boolean equals(Object obj){...}  //需要添加对应的hashCode方法 

  解决:可以添加一个最简单的hashCode方法  

     public int hashCode() {return 0;}   

3.Synchronize on a new "Object" instead

  代码举例:synchronized ("实例化") {...}   //里边必须是对象

  解决: private Object obj ="实例化";

     synchronized (obj ) {...}

4.Close this"FileInputStream" in a "finally" clause.

  解决方法: 在finally中关闭FileInputStream,主要是关闭方式不对,finally代码块中,应该要对每个stream进行单独关闭,而不能统一写在一个try-catch代码中。

5.A"NullPointerException" could be thrown; "tom" is nullablehere

  空指针,解决方式:先判断或者先实例化,再访问里面的属性或者成员。

6.Makethis IP "127.0.0.1" address configurable

  解决方法:不要把IP地址写在此类中,应该在对应的系统文件或者相应的配置文件中配置

7.Either log or rethrow this exception.

  解决方法: 把对应的输出写成Logger.error("aaa“);的形式 

 

8.Do something with the “boolean” value returned by “delete”.

  解决方法: 加删除后的返回值,并对返回值判断,加日志

 

 

 

 
posted @ 2020-12-03 16:32  登风360  阅读(3179)  评论(0编辑  收藏  举报