SonarQube檢測出的bug、漏洞以及異味的修復整理

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也沒有了。
在這裏插入圖片描述

二 漏洞

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.還有一些不知道怎麼清除的異味。

在這裏插入圖片描述
在這裏插入圖片描述
異味有很多,不會清除的異味也肯定不止這些,難清除和不會清除的異味可以先記錄下來。先把容易的好清除的異味清除掉,應該也能達到標準吧,至於難清除的,以後可以一起討論看看怎麼清除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章