一、前置說明:
??官網提供了所有的bug描述信息:官網bug描述鏈接 ,根據findbugs掃碼結果中的關鍵字搜索即可找到bug的描述信息甚至是修復方案。
二、findbugs常見錯誤
Method concatenates strings using + in a loop (SBSC_USE_STRINGBUFFER_CONCATENATION) 錯誤的示范如下:字符串拼接性能太差。應改用StringBuilder實例的append方法。
UC_USELESS_OBJECT 錯誤的示范如下:存在無效的對象。修正方式。刪除無效代碼即可。
UPM_UNCALLED_PRIVATE_METHOD 存在從未調用的私有方法,刪除無效代碼即可
NP_NULL_ON_SOME_PATH_EXCEPTION 在執行的邏輯中,可能報空指針異常。見5. 下面的錯誤示范
NP_NULL_ON_SOME_PATH 在某些路徑上存在空指針。 下面的錯誤示范。若這種bug是業務需要,可以在忽略文件中配置。
@Override
public Result<Integer> addPromotion(PromotionDTO promotionDTO) {Long id = null;try {log.info("promotionDTO = {}", promotionDTO);// NP_NULL_ON_SOME_PATHif (promotionDTO == null) {return Result.wrapError(1, "參數異常");}// 省略部分代碼id = pmpPromotionConfigService.addPromotion(promotionDTO);} catch (Exception e) {// 省略部分代碼}log.info("id = {}", id);// 這里可能報異常return Result.wrapSuccess(id.intValue());
}
DB_DUPLICATE_BRANCHES 復制分支 使用相同的代碼實現條件分支的兩個分支。檢查以確保這不是編碼錯誤。
@Override
public Boolean transformDataIntoMongo(Long promotionId) {try {// 省略部分代碼// 狀態為2 和 else中執行的邏輯相同,請檢查邏輯是否有問題if (status == 2) {promotionMongoDao.save(promotionMongoPO);} else {promotionMongoDao.save(promotionMongoPO);}} catch (Exception e) {logger.error(e.getMessage(), promotionId);return false;}return true;
}
RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE 包含對已知非空值的冗余檢查。
if (StringUtils.isNotEmpty(configStr)) {String[] split = configStr.split(",");// 沒必要再次檢查了if (split != null) {itemTemp.setVoucherList(Arrays.asList(split));}
}
WMI_WRONG_MAP_ITERATOR 錯誤的map迭代器
// 初始化一個map
Map<Integer, List<MarketingActivityPO>> voucherMap = packageMarketingActivityVoucher();
for (Integer key : voucherMap.keySet()) {List<MarketingActivityVoucherPO> voucherPOList = voucherMap.get(key);// 省略部分代碼
}
KeySet(): 將Map中所有的鍵存入到set集合中。因為set具備迭代器。所有可以迭代方式取出所有的鍵,再根據get方法。獲取每一個鍵對應的值。 keySet():迭代后只能通過get()取key
entrySet(): Set<Map.Entry<K,V>> entrySet() //返回此映射中包含的映射關系的 Set 視圖。 Map.Entry表示映射關系。entrySet():迭代后可以e.getKey(),e.getValue()取key和value。返回的是Entry接口 。
雖然使用keyset及entryset來進行遍歷能取得相同的結果,但兩者的遍歷速度是有差別的。
keySet():迭代后只能通過get()取key entrySet():迭代后可以e.getKey(),e.getValue()取key和value。
說明:keySet()的速度比entrySet()慢了很多,也就是keySet方式遍歷Map的性能不如entrySet性能好 為了提高性能,以后多考慮用entrySet()方式來進行遍歷。
RC_REF_COMPARISON 引用類型的比較,應該用equals方法。
private List<FullFreeRuleItems> packageRuleDTO2Param(List<PromotionRuleDTO> ruleDTOList, Long fullFreemeteId) {// 省略for (PromotionRuleDTO ruleDTO : ruleDTOList) {// 不良的比較方式if (ruleDTO.getPromotionMetaId() == fullFreemeteId) {// ......}}
}
UCF_USELESS_CONTROL_FLOW 包含一個無用的控制流語句,在該語句中,無論是否采用分支,控制流都將繼續到同一位置。比如由if語句的語句塊為空導致的:
// 官網demo1,分支下無代碼
if (argv.length == 0) {// TODO: handle this case
}// 官網demo2,空語句導致
if (argv.length == 1);System.out.println("Hello, " + argv[0]);// 項目中的實例
if (area.getAreaType() == 4) { // 級別定位到微倉級 城市大區都要有getAreaType4(singlePromotion, areaCode);
} else if (area.getAreaType() == 3) { // 級別定位到城市級 大區要有 微倉為全部微倉getAreaType3(singlePromotion, areaCode);
} else if (area.getAreaType() == 2) {// 定位到大區級別 不管是全國還是大區,城市 微倉 全部getAreaType(singlePromotion, areaCode);
// 空語句
} else if (area.getAreaType() == 1) {}
DM_BOXED_PRIMITIVE_FOR_PARSING 自動裝箱再拆箱,eg如下:
String reduceStep = "123";
// 把字符串轉成基本類型、然后封裝成包裹類型,參與比較時又要自動拆箱
if (perReduce.intValue() >= Integer.valueOf(reduceStep))) {// 省略部分邏輯
}
源碼解釋: 改為parseXXX方法較為合適。
// valueOf把字符串轉成基本類型、然后封裝成包裹類型。
public static Integer valueOf(String s, int radix) throws NumberFormatException {return Integer.valueOf(parseInt(s,radix));
}
// parseXXX方法可以把字符串轉成基本類型
public static int parseInt(String s, int radix) throws NumberFormatException
RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE 某個值雖然在某處有被判斷是否為null,但是這個值在該處并不可以為null,因為這個值被提前引用了,如果他有可能是null,在被引用的時候就會產生空指針異常,所以這里的判斷也就是多余的,而在該判斷之前的引用也可能是錯誤的。
List<Integer> activityIdList = new ArrayList<>();
// 被重新賦值后,有可能變為null
activityIdList = activityDao.getXXX(searchDTO);
logger.info("查找到的活動個數:{}", activityIdList.size());
// 上一行已經使用過該引用,下一行再判空,為時已晚。需要更改判空的時機
if (activityIdList == null) {// 省略部分邏輯
}
RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT
@Override
@Transactional(rollbackFor = Exception.class)
public Result<Integer> batchCheckPromotion(List<String> idList, String userName) {if (CollectionUtils.isEmpty(idList)) {// 該調用沒有副作用,且返回值還被忽略了Result.wrapError(1, "傳入的id列表為空!");}// 省略部分邏輯
}
總結
以上是生活随笔 為你收集整理的findbugs常见错误总结 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。