Use try-with-resources or close this "BufferedOutputStream" in a "finally" clause.
參考:https://blog.csdn.net/libusi001/article/details/103848922
解決方法: 在finally中關閉FileInputStream,主要是關閉方式不對,finally代碼塊中,應該要對每個stream進行單獨關閉,而不能統一寫在一個try-catch代碼中。
A NullPointerException might be thrown as ‘XXX’ is nullable here.
空指針,解決方式:先判斷或者先實例化,再訪問里面的屬性或者成員。
Use a “double” or “BigDecimal” instead.
說明:兩個float計算會產生不精確的結果
解決方案:將float換為double或者BigDecimal計算
舉例:
float a = 16777216.0f;
float b = 1.0f;
float c = a + b; // Noncompliant; yields 1.6777216E7 not 1.6777217E7
double d = a + b; // Noncompliant; addition is still between 2 floats
換為
float a = 16777216.0f;
float b = 1.0f;
BigDecimal c = BigDecimal.valueOf(a).add(BigDecimal.valueOf(b));
double d = (double)a + (double)b;
Cast one of the operands of this multiplication operation to a “long”
說明:int數運算最終再把結果轉為long將有可能產生溢出
解決方案:轉換為long型預算
舉例:
long bigNum = Integer.MAX_VALUE + 2; // Noncompliant. Yields -2147483647
換為
long bigNum = Integer.MAX_VALUE + 2L;
Close this “XXX”.
說明:流沒有顯示的關閉。
解決方案:在fianlly語句塊內關閉。
Remove or correct this useless self-assignment.
說明:缺少this
解決方案:用this.xxx=xxx來替代
舉例:
public void setName(String name) {
name = name;
}
換為
public void setName(String name) {
this.name = name;
}
Correct this “&” to “&&”.
說明:錯誤的使用&和&&
解決方案:根據情況使用&和&&
This branch can not be reached because the condition duplicates a previous condition in the same sequence of “if/else if” statements
說明:if else if 語句判斷條件重復
解決方案:去掉多余的判斷條件
Make this “XXX” field final.
說明:將某個字段置為final,常見在Exception的參數
解決方案:將字段置為final
Remove this call to “equals”; comparisons between unrelated types always return false.
說明:去掉equals判斷語句,因為總為false
解決方案:去掉equals語句
Remove this return statement from this finally block.
說明:在finally語句塊中有return語句
解決方案:去掉finally語句塊的return語句或者放在finally語句塊之外
Remove this continue statement from this finally block.
說明:在finally語句塊中有continue語句
解決方案:去掉finally語句塊中的continue語句或者放在finally語句塊之外
Equality tests should not be made with floating point values.
說明:浮點數之間用 == 來比較大小不准確
解決方案:用Number或者BigDecimal來比較
舉例:
float myNumber = 3.146;
if ( myNumber == 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be false
// …
}
if ( myNumber != 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be true
// …
}
Add a type test to this method.
說明:強轉前未判斷類型
解決方案:強轉前先判斷類型
舉例:
ErpVO ev = (ErpVO) obj;
return this.userCode.equals(ev.getUserCode());
換為
if (obj == null) {
return false;
}
if (obj.getClass() != this.getClass()) {
return false;
}
…
Add an end condition to this loop.
說明:沒有退出條件
解決方案:根據情況來決定方法的退出條件
Make “XXX” an instance variable.
說明:有些類不是線程安全的,將變量生命為靜態的可能會導致線程安全問題
解決方案:將變量聲明為實例的。
Strings and Boxed types should be compared using "equals()"
字符串和包裝類型對比時應該使用equals方法。
解釋
使用引用相等==或!=比較java.lang.String或包裝類型(如java.lang.Integer)的兩個實例幾乎總是false,因為它不是在比較實際值,而是在內存中的位置(地址)。
在Java 中包裝類型與基本數據類型存儲位置不同。
-
Java 基本數據類型存放位置
方法參數、局部變量存放在棧內存中的棧楨中的局部變量表
常量存放在常量池中 -
包裝類型如Integer存放位置
常量池
堆內存
Integer 存儲在常量池中時可以使用對比,但當在堆內存中時,使用對比,實際對比的是兩個內存地址而非值。
Reduce the number of conditional operators (4) used in the expression (maximum allowed 3)
在一個表達式中條件判斷不應該超過三個
//修改前
boolean rollback = (receiveType == Constants.ONE || receiveType == Constants.TWO || receiveType == Constants.THREE) && (result == null || !result.isSuccess());
//修改后,提取成一個方法
boolean rollback = checkReceiveType(receiveType) && (result == null || !result.isSuccess());
private boolean checkReceiveType(int receiveType) {
return receiveType == Constants.ONE || receiveType == Constants.TWO || receiveType == Constants.THREE;
}
The Cyclomatic Complexity of this method "xxx" is 19 which is greater than 15 authorized.
代碼的復雜度太高了,通常可以把代碼中獨立的業務邏輯抽取成單獨的方法;
sonar掃描是按照一個條件判斷算一個復雜度的,也就是說在一個方法中不要寫超過15個條件判斷;
靈活使用StringUtils.isAnyBlank/isNoneBlank/BooleanUtils.and/BooleanUtils.or可以把多個條件判斷變成一個
//修改前
if(this.acId== null||this.userId==null||!Md5Util.encrypt(inputSign).equals(this.getMd5Sign())){
flag = false;
}
//修改后
if(StringUtils.isAnyBlank(this.acId,this.userId)||!Md5Util.encrypt(inputSign).equals(this.getMd5Sign())){
flag = false;
}
Return an empty collection instead of null
不能直接返回null
//修改前
return null
//修改后
return Collections.emptyList()/Collections.EmptyMap/Collections.EmptySet/new String[0]
Refactor this code to not nest more than 5 if/for/while/switch/try statements.
if/for/while/switch/try嵌套不能超過5層
Iterate over the "entrySet" instead of the "keySet"
遍歷map時,使用entrySet,而不是keySet;
解釋
"entrySet()" should be iterated when both the key and value are needed;
通過查看源代碼發現,調用方法keySetMap.keySet()會生成KeyIterator迭代器,其next方法只返回其key值,而調用entrySetMap.entrySet()方法會生成EntryIterator 迭代器,其next方法返回一個Entry對象的一個實例,其中包含key和value。
所以當我們用到key和value時,用entrySet迭代性能更高
Use "Integer.parseInt" for this string-to-int conversion
使用Integer.parseInt 代替 Integer.valueOf
解釋
Integer.parseInt(s)是把字符串解析成int基本類型,
Integer.valueOf(s)是把字符串解析成Integer對象類型
Replace "Collections.EMPTY_LIST" by "Collections.emptyList()
Collections.EMPTY_LIST VS Collections.emptyList()
Collections. emptyList()返回的也是一個空的List,它與Collections.EMPTY_LIST的唯一區別是,Collections. emptyList()支持泛型,所以在需要泛型的時候,可以使用Collections. emptyList()。
注意,這個空的集合是不能調用add來添加元素的,會直接拋異常
為啥不直接new ArrayList()呢?
因為new ArrayList()在初始化時會占用一定的資源
————————————————
參考:
https://blog.csdn.net/asdasd3418/article/details/83791630/
https://www.jianshu.com/p/f67a6f18e066