2.findbugs總結

 

一 Bad practice(壞實現)

  1.Confusing method name

    a.Class names shouldn't shadow simple name of implemented interface

This class/interface has a simple name that is identical to that of an implemented/extended interface, except that the interface is in a different package (e.g., alpha.Foo extends beta.Foo). This can be exceptionally confusing, create lots of situations in which you have to look at import statements to resolve references and creates many opportunities to accidentally define methods that do not override methods in their superclasses.

不要定義與實現接口名一樣的類/接口名

 1 public interface BaseMapper<T> extends com.baomidou.mybatisplus.mapper.BaseMapper<T> {
 2     public interface BaseMappers<T> extends com.baomidou.mybatisplus.mapper.BaseMapper<T> {
 3     //特別注意,由於繼承了通用BaseMapper,該接口不能被掃描到,否則會出錯,MapperScan(value="com.letsun.**.mapper*",markerInterface=CommonMapper.class)
 4     
 5     /**
 6      * 自定義多表複雜查詢  
 7      * @param map
 8      * @param page
 9      * @return List<T>
10      * @author xx<2018年4月12日>
11      */
12     List<T>  selectComplex(Map<String,Object> map,Pagination page);
13 }

 

     b.Method names should start with a lower case letter()

Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.

方法應該是動詞,並且首字母小寫其他內部單詞大寫

 1 //獲取下一個位置,並移動起始位置
 2     public final boolean GetNextgetNext(Out<String> strMsg) {
 3         strMsg.setData("");
 4 
 5         //
 6         if (m_end == m_start) {
 7             return false;
 8         }
 9 
10         strMsg.setData(m_ringList[m_start]);
11         m_start = (m_start + 1) % m_capacity;
12 
13         return true;
14     }

 

     c.Class names should start with an upper case letter

Class names should be nouns, in mixed case with the first letter of each internal word capitalized. Try to keep your class names simple and descriptive. Use whole words-avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as URL or HTML).

類名首字母應該大寫

1 public class testTest {}

 

     d.Field names should start with a lower case letter

Names of fields that are not final should be in mixed case with a lowercase first letter and the first letters of subsequent words capitalized.

不是final的類屬性首字母應小寫

1 public class OrderApiConfig {
2     
3     public static String Base base = "tms.";
4 }

 

     e.Class is not derived from an Exception,even though it is named as such

This class is not derived from another exception, but ends with 'Exception'. This will be confusing to users of this class.

Class沒有繼承Exception,雖然名字像一個異常,不能這樣命名,會產生誤解

1 public class GpsException extends AbsIniFilter
2 {
3     @Override
4     public void Excute()
5     {
6         this.getenumActionCategory(), this.getenumActionType(), TaAutoScheduleLog.EnumContentType.GpsException, TaAutoScheduleLog.EnumTppe.GpsException, "", "", OperUser);
7     }
8 }

 

  2.Mutable enum field

    a.Enum field is public and mutable

A mutable public field is defined inside a public enum, thus can be changed by malicious code or by accident from another package. Though mutable enum fields may be used for lazy initialization, it's a bad practice to expose them to the outer world. Consider declaring this field final and/or package-private.

枚舉對象的某個屬性不應該是public,儘管可變枚舉屬性會執行懶加載。應考慮用final及/或private修飾屬性。

 1 public enum EnumInvalid {
 2     No(20),Yes(10);
 3     
 4     public final int code;
 5     
 6     EnumInvalid(int code) {
 7         this.code = code;
 8     }
 9     public static EnumInvalid getByCode(int code) {
10         EnumInvalid[] enums = EnumInvalid.values();
11         for (EnumInvalid dd_TypeEnum : enums) {
12             if (dd_TypeEnum.code == code) {
13                 return dd_TypeEnum;
14             }
15         }
16         return null;
17     }
18 }

 

     b.Public enum method unconditionally sets its field

This public method declared in public enum unconditionally sets enum field, thus this field can be changed by malicious code or by accident from another package. Though mutable enum fields may be used for lazy initialization, it's a bad practice to expose them to the outer world. Consider removing this method or declaring it package-private.

私有方法應該使用private

 1 public enum EnumCode {
 2         /**
 3          * 訂單異常
 4          * 
 5          */
 6         // [Description("訂單異常")]
 7         order_exception(-3,"訂單異常");
 8 
 9         private int intValue;
10         
11         private String name;
12         private static java.util.HashMap<Integer, EnumCode> mappings;
13 
14         private synchronized static java.util.HashMap<Integer, EnumCode> getMappings() {
15             if (mappings == null) {
16                 mappings = new java.util.HashMap<Integer, EnumCode>();
17             }
18             return mappings;
19         }
20 
21         private EnumCode(int value,String name) {
22             intValue = value;
23             this.name = name;
24             EnumCode.getMappings().put(value, this);
25         }
26 
27         public int getValue() {
28             return intValue;
29         }
30 
31         public static EnumCode forValue(int value) {
32             return getMappings().get(value);
33         }
34         
35         
36         public static String getValueByCode(Integer code) {
37             for (EnumCode platformFree : EnumCode.values()) {
38                 if (code.equals(platformFree.intValue)) {
39                     return platformFree.getName();
40                 }
41             }
42             return null;
43         }
44  
45         public String getName() {
46             return name;
47         }
48 
49         public int getIntValue() {
50             return intValue;
51         }
52 
53         public void setIntValue(int intValue) {
54             this.intValue = intValue;
55         }
56                 private void setIntValue(int intValue) {
57             this.intValue = intValue;
58         }
59 
60         public void setName(String name) {
61             this.name = name;
62         }
63         private void setName(String name) {
64             this.name = name;
65         }
66     }            

 

  3.Bad use of return value from method

    a.Method ignores exceptional return value

This method returns a value that is not checked. The return value should be checked since it can indicate an unusual or unexpected function execution. For example, the File.delete() method returns false if the file could not be successfully deleted (rather than throwing an Exception). If you don't check the result, you won't notice if the method invocation signals unexpected behavior by returning an atypical return value.

方法忽略了異常返回值,需捕獲

 

 1 private static void CreateDirectory(String directory) {
 2         File file = new File(directory);
 3         if (!file.exists() || !file.isDirectory()) {
 4             try {
 5                 file.mkdirs();
 6             }
 7             catch (Exception ex)
 8             {
 9                 throw ex;
10             }
11         }
12     }

 

 

 

  4.Stream not colsed on all paths

    a.Mathod may fail to close stream

The method creates an IO stream object, does not assign it to any fields, pass it to other methods that might close it, or return it, and does not appear to close the stream on all paths out of the method.  This may result in a file descriptor leak.  It is generally a good idea to use a finally block to ensure that streams are closed.

需確保數據流關閉

 1 public static String doPost(final Map<String, Object> strParams, final Map<String, File> fileParams) {
 2         HttpURLConnection conn = null;
 3         try {
 4             URL url = new URL(Const.ErpfileUrl);
 5             conn = (HttpURLConnection) url.openConnection();
 6             conn.setRequestMethod("POST");
 7             conn.setReadTimeout(TIME_OUT);
 8             conn.setConnectTimeout(TIME_OUT);
 9             conn.setDoOutput(true);
10             conn.setDoInput(true);
11             conn.setUseCaches(false);// Post 請求不能使用緩存
12             // 設置請求頭參數
13             conn.setRequestProperty("Connection", "Keep-Alive");
14             conn.setRequestProperty("Charset", "UTF-8");
15             conn.setRequestProperty("Content-Type", CONTENT_TYPE + "; boundary=" + BOUNDARY);
16             /**
17              * 請求體
18              */
19             // 上傳參數
20             DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
21             // getStrParams()爲一個
22             dos.writeBytes(getStrParams(strParams).toString());
23             dos.flush();
24 
25             // 文件上傳
26             StringBuilder fileSb = new StringBuilder();
27             for (Map.Entry<String, File> fileEntry : fileParams.entrySet()) {
28                 fileSb.append(PREFIX).append(BOUNDARY).append(LINE_END)
29                         /**
30                          * 這裏重點注意: name裏面的值爲服務端需要的key 只有這個key 纔可以得到對應的文件 filename是文件的名字,包含後綴名的
31                          * 比如:abc.png
32                          */
33                         .append("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileEntry.getKey() + "\"" + LINE_END)
34                         .append("Content-Type: */*" + LINE_END) // 此處的ContentType不同於 請求頭 中Content-Type
35                         .append(LINE_END);// 參數頭設置完以後需要兩個換行,然後纔是參數內容
36                 dos.writeBytes(fileSb.toString());
37                 dos.flush();
38                 InputStream is = new FileInputStream(fileEntry.getValue());
39                 byte[] buffer = new byte[1024];
40                 int len = 0;
41                 while ((len = is.read(buffer)) != -1) {
42                     dos.write(buffer, 0, len);
43                 }
44                 is.close();
45                 dos.writeBytes(LINE_END);
46             }
47             // 請求結束標誌
48             dos.writeBytes(PREFIX + BOUNDARY + PREFIX + LINE_END);
49             dos.flush();
50             dos.close();
51 
52             BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
53             StringBuilder response = new StringBuilder();
54             String line = null;
55             while ((line = reader.readLine()) != null) {
56                 response.append(line);
57             }
58             reader.close();
59             return response.toString();
60         } catch (Exception e) {
61             e.printStackTrace();
62         } finally {
63             if (conn != null) {
64                 conn.disconnect();
65             }
66         }
67 
68         return "";
69     }

 

  5.Dubious method invocation

    a.Adding elements of an entry set may fail due to reuse of Entry objects

The entrySet() method is allowed to return a view of the underlying Map in which a single Entry object is reused and returned during the iteration. As of Java 1.6, both IdentityHashMap and EnumMap did so. When iterating through such a Map, the Entry value is only valid until you advance to the next iteration. If, for example, you try to pass such an entrySet to an addAll method, things will go badly wrong.

一個入口的添加可能因爲重用Entry對象導致失敗,entrySet()方法允許重複使用導致數據異常。

 1 public static String sortMapForSign(Map<String, Object> paramMap, String accessKey) {
 2         TreeMap<String,Object> treeMap=new TreeMap<>();
 3         treeMap.putAll(paramMap);
 4         // 參數排序
 5         List<Map.Entry<String, Object>> entryList = new ArrayList<>();
 6         entryList.addAll(paramMap.entrySet());
 7         Collections.sort(entryList, (o1, o2) -> o1.getKey().compareTo(o2.getKey()));
 8         // 拼接成待簽名串
 9         StringBuffer sb = new StringBuffer(accessKey);
10         for (Map.Entry<String, Object> entry : entryList) {
11         for (Map.Entry<String, Object> entry : treeMap.entrySet()) {
12             String paramKey = entry.getKey();
13             sb.append(paramKey + entry.getValue());
14         }
15         String nativSign = Md5Utils.md5Encode(sb.toString()).toUpperCase();
16         return nativSign;
17     }

 

  6.Bad implementation of Serializable class

    a.Class defines clone() but doesn't implement Cloneable

This class defines a clone() method but the class doesn't implement Cloneable. There are some situations in which this is OK (e.g., you want to control how subclasses can clone themselves), but just make sure that this is what you intended.

類定義了clone()但沒有實現Cloneable

 1 private static class Distance {
 2 private static class Distance implements Cloneable {
 3         /**
 4          * 
 5          * 
 6          */
 7         public BigDecimal QH_distance = new BigDecimal(0);
 8         /**
 9          * 
10          * 
11          */
12         public BigDecimal PH_distance = new BigDecimal(0);
13 
14         public Distance clone() {
15             Distance varCopy = new Distance();
16 
17             varCopy.QH_distance = this.QH_distance;
18             varCopy.PH_distance = this.PH_distance;
19 
20             return varCopy;
21         }
22 
23         public void setQH_distance(BigDecimal qh_distance2) {
24             // TODO Auto-generated method stub
25 
26         }
27 
28         public void setPH_distance(BigDecimal ph_distance2) {
29             // TODO Auto-generated method stub
30 
31         }
32     }

 

  7.Incorrect definition of Serializable class

    a.serialVersionUID isn't final

This class defines a serialVersionUID field that is not final.  The field should be made final if it is intended to specify the version UID for purposes of serialization.

serialVersionUID不是final的

1 public class GetTaskStatusByCarModel implements Serializable {
2     /**
3      * @Fields serialVersionUID : TODO
4      */
5     private static  long serialVersionUID = 1L;
6     private static final long serialVersionUID = 1L;
7 }

 

    b.Comparator doesn't implement Serializable

This class implements the Comparator interface. You should consider whether or not it should also implement the Serializable interface. If a comparator is used to construct an ordered collection such as a TreeMap, then the TreeMap will be serializable only if the comparator is also serializable. As most comparators have little or no state, making them serializable is generally easy and good defensive programming.

Comparator沒有實現Serializable

1 class MyComparator implements Comparator<GetHistoryConsumedTimeModel> { 
2     class MyComparator implements Comparator<GetHistoryConsumedTimeModel>, Serializable {
3     @Override
4     public int compare(GetHistoryConsumedTimeModel s1, GetHistoryConsumedTimeModel s2) {
5         int num = s1.getval().intValue() - s2.getval().intValue();
6         int num1 = (num == 0 ? s1.getID().compareTo(s2.getID()) : num);
7         return num1;
8     }
9 }

 

  8.Format string problem

    a.Format string should use %n rather than \n

This format string include a newline character (\n). In format strings, it is generally preferable better to use %n, which will produce the platform-specific line separator.

格式化代碼應該使用%n代替\n

1             sbLog.append(String.format("請求路徑: %s%n", request.getRequestURL().toString()));
2             sbLog.append(String.format("請求方式: %s\r\n", request.getMethod()));
3             sbLog.append(String.format("請求類名: %s\r\n", joinPoint.getSignature().getDeclaringTypeName()));
4     

 

  9.Dropped or ignored exception

    a.Method might ignore exception

This method might ignore an exception.  In general, exceptions should be handled or reported in some way, or they should be thrown out of the method.

異常需捕獲或者手動處理。

 1 if (StringUtils.isNotBlank(bagReq.getNeedToDate())) {
 2             try {
 3                 
 4                 SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy",Locale.US);
 5                 Date d=sdf.parse(bagReq.getNeedToDate());
 6                 sdf = new SimpleDateFormat("yyyy-MM-dd",Locale.US);
 7                 wrapper.eq("NeedToDate", sdf.format(d));
 8             } catch (Exception e) {
 9                 // TODO: handle exception
10             }
11              
12         }

 

  10.Checking String equality using == or !=(嚴重)

    a.Comparison of String objects using == or !=

This code compares java.lang.String objects for reference equality using the == or != operators. Unless both strings are either constants in a source file, or have been interned using the String.intern() method, the same string value may be represented by two different String objects. Consider using the equals(Object) method instead

對象的比較不要使用==和!=,要使用equals方法

 1 private static <T> boolean IsCanCompare(Class<T> t) {
 2         if (t.isAssignableFrom(Comparable.class)) { //(t.IsValueType) {
 3             return true;
 4         } else {
 5             // String是特殊的引用類型
 6             if (t.getName() == String.class.getName()) {
 7                 return true;
 8             }
 9             if(t.getName().equals(String.class.getName()))
10             {
11                 return true;
12             }
13             return false;
14         }
15     }    

 

二 Correctness(一般的正確性問題,可能導致錯誤的代碼)

  1.Null pointer dereference

    a.Possible null pointer dereference

There is a branch of statement that, if executed, guarantees that a null value will be dereferenced, which would generate a NullPointerException when the code is executed. Of course, the problem might be that the branch or statement is infeasible and that the null pointer exception can't ever be executed; deciding that is beyond the ability of FindBugs.

 1 public int UpdateBagState(String waybillNo, String operationMan) {
 2         String tWaybingllNo ="";
 3         if(null != waybillNo && waybillNo.contains(",")) {
 4             String[] tWaybillNoArr = waybillNo.split(",");
 5             if(tWaybillNoArr[0].length() == 0) {
 6                 tWaybingllNo = tWaybillNoArr[0];
 7             }else {
 8                 return 0;
 9             }
10             
11         }else {
12             if(null != waybillNo&&waybillNo.length() == 0) {
13                 return 0;
14             }else {
15                 tWaybingllNo = waybillNo;
16             }
17         }

 

    b.Possible null pointer dereference in method on exception path

A reference value which is null on some exception control path is dereferenced here.  This may lead to a NullPointerException when the code is executed.  Note that because FindBugs currently does not prune infeasible exception paths, this may be a false warning.
Also note that FindBugs considers the default case of a switch statement to be an exception path, since the default case is often infeasible.

 1 public PickupingScan GetPickupingScanByTaskNo(String taskNo) {
 2         String url = ApiConfig.Pickup;
 3         Map<String, Object> requestParameters = new HashMap<String, Object>();
 4         requestParameters.put("elasticsearchFlag", "N");
 5         requestParameters.put("countFlag", "N");
 6         requestParameters.put("page", 1);
 7         requestParameters.put("pageSize", 10);
 8         Map<String, Object> obj1 = new HashMap<String, Object>();
 9         List<Object> list1 = new ArrayList<Object>();
10         Map<String, Object> obj2 = new HashMap<String, Object>();
11         obj2.put("conditionOperation", "");
12         obj2.put("propertyName", "orderNumber");
13         List<Object> list2 = new ArrayList<Object>();
14         list2.add(taskNo);
15         obj2.put("values", list2);
16         obj2.put("postBrackets", ")");
17         obj2.put("type", "string");
18         obj2.put("frontBrackets", "(");
19         obj2.put("operation", "equal");
20         obj2.put("columnName", "order_number");
21         list1.add(obj2);
22         obj1.put("vos", list1);
23         requestParameters.put("generic", obj1);
24         String res = ASMOpenApi.request(url,requestParameters );
25         if (StringUtils.isNotBlank(res)) {
26             ObjectMapper mapper = new ObjectMapper();
27             mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
28             KyeResponse<CommonResult<Pickup>> responseModel = null;
29             try {
30                 responseModel = mapper.readValue(res, new com.fasterxml.jackson.core.type.TypeReference<Response<CommonResult<Pickup>>>() {
31                 });
32             } catch (IOException e) {
33                 e.printStackTrace();
34             }
35 //            Response<CommonResult<Pickup>> responseModel = JSONObject.parseObject(res, new TypeReference<Response<CommonResult<Pickup>>>() {
36 //            });
37             if (responseModel!=null||responseModel.isFail())
38                 return null;
39             if (responseModel.getData() == null || responseModel.getData().getrows() == null || responseModel.getData().getrows().size() == 0)
40                 return null;
41             return ConfigConverter.MapConfigToPickupingScan(responseModel.getData().getrows().get(0));
42         }
43         return null;
44     }

 

    c.Non-virtual method call passes null for non-null parameter

A possibly-null value is passed to a non-null method parameter. Either the parameter is annotated as a parameter that should always be non-null, or analysis has shown that it will always be dereferenced.

可能爲null的值將傳遞給非null方法參數。 要麼將參數註釋爲應始終爲非null的參數,要麼分析表明它將始終被取消引用。

Response<GetTaskHistoryConsumedTime> result = autoScheduleCoreHelper.GetHistoryConsumedTime(_type, company_no, number, weight,null"", departName);
        

 

    d.Null pointer dereference(嚴重)

A null pointer is dereferenced here.  This will lead to a NullPointerException when the code is executed.

 1 public List<AddSubscribeCusomterModel> OrderNoValid(String orderNo) {
 2 
 3         TaTask taskEntity = null;
 4         this.OrderNoValidCheck(orderNo, taskEntity);
 5         AddSubscribeCusomterModel newModel = new AddSubscribeCusomterModel();
 6         newModel.setorderno(orderNo);
 7         if(taskEntity!=null)
 8         {
 9             newModel.setcompanyname(taskEntity.getCol007());
10             newModel.setcarno(taskEntity.getCarNo());
11             newModel.setappointment_name(taskEntity.getCol008());
12             newModel.setType(taskEntity.getType() + "");
13         }
14         List<AddSubscribeCusomterModel> lst = new ArrayList<AddSubscribeCusomterModel>();
15         lst.add(newModel);
16         return lst;
17     }

 

    e.Read of unwritten field

The program is dereferencing a field that does not seem to ever have a non-null value written to it. Unless the field is initialized via some mechanism not seen by the analysis, dereferencing this value will generate a null pointer exception.

此字段是永遠不會寫入值,如果不需要的話就刪除掉

 1 public class StopUnFinishTask extends AbsDispatch
 2 {
 3     
 4     
 5     private TaManualLogNew.EnumManualSubType _enumManualSubType = TaManualLogNew.EnumManualSubType.Manual_StopUnFinishTask;
 6     @Override
 7     protected TaManualLogNew.EnumManualSubType getenumManualSubType()
 8     {
 9         return _enumManualSubType;
10     }
11     @Override
12     protected void setenumManualSubType(TaManualLogNew.EnumManualSubType value)
13     {
14         _enumManualSubType = value;
15     }
16     
17 }

 

    f.Method call passes null for non-null parameter

This method call passes a null value for a non-null method parameter. Either the parameter is annotated as a parameter that should always be non-null, or analysis has shown that it will always be dereferenced.

方法調用傳遞null給非空參數

 1 public static String encode(String unencoded) {
 2         byte[] bytes = null;
 3         try {
 4             bytes = unencoded.getBytes("UTF-8");
 5         } catch (UnsupportedEncodingException ignored) {
 6         }
 7         if(bytes!=null)
 8         {
 9             return encode(bytes);
10         }
11         return null;
12     }

 

    g.Value is null and guaranteed to be dereferenced on exception path

There is a statement or branch on an exception path that if executed guarantees that a value is null at this point, and that value that is guaranteed to be dereferenced (except on forward paths involving runtime exceptions)

null值會在exception處理中被用到

 1 public static String doPost(String url, Map<String, String> param,Map<String, String> hearer) {
 2         // 創建Httpclient對象
 3         CloseableHttpClient httpClient = HttpClients.createDefault();
 4         CloseableHttpResponse response = null;
 5         String resultString = "";
 6         try {
 7             // 創建Http Post請求
 8             HttpPost httpPost = new HttpPost(url);
 9             if (hearer != null && !hearer.isEmpty()) {
10                 for (Entry<String, String> enty : hearer.entrySet()) {
11                     httpPost.addHeader(enty.getKey(), enty.getValue());
12                 }
13             }
14             // 創建參數列表
15             if (param != null) {
16                 List<NameValuePair> paramList = new ArrayList<NameValuePair>();
17                 for (String key : param.keySet()) {
18                     paramList.add(new BasicNameValuePair(key, param.get(key)));
19                 }
20                 // 模擬表單
21                 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
22                 httpPost.setEntity(entity);
23             }
24             // 執行http請求
25             response = httpClient.execute(httpPost);
26             resultString = EntityUtils.toString(response.getEntity(), "utf-8");
27         } catch (Exception e) {
28             e.printStackTrace();
29         } finally {
30             try {
31                 if(response!=null)
32                 {
33                     response.close();
34                 }
35             } catch (IOException e) {
36                 e.printStackTrace();
37             }
38         }
39         return resultString;
40     }

 

  2.Redundant comparison to null

    a.Nullcheck of value previously dereferenced

A value is checked here to see whether it is null, but this value can't be null because it was previously dereferenced and if it were null a null pointer exception would have occurred at the earlier dereference. Essentially, this code and the previous dereference disagree as to whether this value is allowed to be null. Either the check is redundant or the previous dereference is erroneous.

對一個已經使用的值進行了null檢測

 1 private TA_ZWICRecordset GetRecordset(Map<String, Object> dic, String url) {
 2         String res = OpenApi.request(url, dic);
 3         if (StringUtils.isNotBlank(res)) {
 4             ObjectMapper mapper = new ObjectMapper();
 5             mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
 6             Response<ERPResponseResult<RecordSetResponseModel>> responseModel = null;
 7             try {
 8                 responseModel = mapper.readValue(res, new com.fasterxml.jackson.core.type.TypeReference<Response<ERPResponseResult<RecordSetResponseModel>>>() {
 9                 });
10             } catch (IOException e) {
11                 e.printStackTrace();
12             }
13             if (responseModel == null || responseModel.isFail() || responseModel.getData() == null || responseModel.getData().getRows() == null)
14                 return null;
15 
16             List<RecordSetResponseModel> models = responseModel.getData().getRows();
17 
18             Collections.sort(models, new Comparator<RecordSetResponseModel>() {
19                 @Override
20                 public int compare(RecordSetResponseModel o1, RecordSetResponseModel o2) {
21                     return o2.getCol_006() > o1.getCol_006() ? 1 : -1;
22                 }
23             });
24             
25             if(models!=null && models.size()>0)
26             {
27                 return RecordSetConverter.ToEntity(models.get(0));
28             }            
29         }
30         return null;
31     }

 

  3.Suspicious bitwise logical expression

    a.BitWise OR of signed byte value

Loads a byte value (e.g., a value loaded from a byte array or returned by a method with return type byte) and performs a bitwise OR with that value. Byte values are sign extended to 32 bits before any any bitwise operations are performed on the value. Thus, if b[0] contains the value 0xff, and x is initially 0, then the code ((x << 8) | b[0]) will sign extend 0xff to get 0xffffffff, and thus give the value 0xffffffff as the result.
In particular, the following code for packing a byte array into an int is badly wrong:
int result = 0;
for(int i = 0; i < 4; i++)
result = ((result << 8) | b[i]);
The following idiom will work instead:
int result = 0;
for(int i = 0; i < 4; i++)
result = ((result << 8) | (b[i] & 0xff));

不能 在帶符號的byte值上進行位OR運算

 1  private static long byteArrayToLong(byte[] b) {
 2         long resultHigh = 0;
 3         long resultLow = 0;
 4         for (int i = 0; i < b.length; i = i + 2) {
 5             resultHigh = resultHigh << 8 | b[i];
 6             resultHigh = ((resultHigh << 8) | (b[i]&0xff));
 7             resultLow = resultLow << 8 | b[i + 1];
 8             resultLow = (resultLow << 8) | (b[i + 1]&0xff);
 9         }
10 
11         return resultHigh ^ resultLow;
12     }

 

  4.Casting from integer values

    a.Integral value cast to double and then passed to Math.ceil

This code converts an integral value (e.g., int or long) to a double precision floating point number and then passing the result to the Math.ceil() function, which rounds a double to the next higher integer value. This operation should always be a no-op, since the converting an integer to a double should give a number with no fractional part. It is likely that the operation that generated the value to be passed to Math.ceil was intended to be performed using double precision floating point arithmetic.

不能int轉換成double,然後傳遞給Math.ceil

 1 public ERPResponseResult(List<T> models, int rowTotal, int page, String pagesizestr) {
 2         Integer curentpagesize = 1;
 3         if (!StringUtils.isBlank(pagesizestr)) {
 4             curentpagesize = Ints.tryParse(pagesizestr);
 5         }
 6         if (curentpagesize == null) {
 7             curentpagesize = 0;
 8         }
 9         this.setRows(models);
10         this.setRowTotal(rowTotal);
11         this.setPage(page);
12         this.setPageSize(curentpagesize);
13         this.setPageTotal(getPageSize() == 0 ? getPageSize() : (int) Math.ceil(Double.parseDouble(Integer.toString(rowTotal))/ Double.parseDouble(Integer.toString(getPageSize()))));
14         // erpResult.pageTotal = rowTotal / erpResult.pageSize;
15     }

 

  5.Format string problem

    a.MessageFormat supplied where printf style format expected(嚴重)

A method is called that expects a Java printf format string and a list of arguments. However, the format string doesn't contain any format specifiers (e.g., %s) but does contain message format elements (e.g., {0}). It is likely that the code is supplying a MessageFormat string when a printf-style format string is required. At runtime, all of the arguments will be ignored and the format string will be returned exactly as provided without any formatting.

需要使用printf樣式時使用了MessageFormat

1 mDebugLog.append("\n").append(String.format("TaskJson:{0}%s", taskJson));

 

    b.More arguments are passed than are actually used in the format string

A format-string method with a variable number of arguments is called, but more arguments are passed than are actually used by the format string. This won't cause a runtime exception, but the code may be silently omitting information that was intended to be included in the formatted string.

缺少佔位符

1 FileLogHelper.Error(String.format("【UpdataCarDepart】根據車牌更新點部失敗 車牌:%s 點部:%s 原因:%s", model.getcarno(),model.getdepart(),ex.getMessage()));
2        

 

  6.Dubious method invocation

    a.Bad constant value for month(嚴重)

This code passes a constant month value outside the expected range of 0..11 to a method.

 對於month錯誤的常量值

 1 public static Date getLastMonthTime(boolean startOrEnd) {
 2         Calendar calendar = Calendar.getInstance();
 3         int month = calendar.get(Calendar.MONTH) - 1;
 4         int year = calendar.get(Calendar.YEAR);
 5         Date dtStart;
 6         Date dtEnd;
 7         if (month == 0) { // 表示上月爲12月 去年的
 8             calendar.set(year - 1, 1211, 1);
 9             dtStart = calendar.getTime();
10             calendar.set(year - 1, 1211, 31, 23, 59, 59);
11             dtEnd = calendar.getTime();
12         } else {
13 //            dtStart = new Date(new Date().Year, month, 1);
14             calendar.set(year, month, 1);
15             dtStart = calendar.getTime();
16             calendar.add(Calendar.MONTH, 1);
17             calendar.add(Calendar.SECOND, -1);
18             dtEnd = calendar.getTime();
19         }
20         return startOrEnd ? dtStart : dtEnd;
21     }

 

  7.Regular expressions

    a."." or "|" used for regular expression(嚴重)

A String function is being invoked and "." or "|" is being passed to a parameter that takes a regular expression as an argument. Is this what you intended? For example
s.replaceAll(".", "/") will return a String in which every character has been replaced by a '/' character
s.split(".") always returns a zero length array of String
"ab|cd".replaceAll("|", "/") will return "/a/b/|/c/d/"
"ab|cd".split("|") will return array with six (!) elements: [, a, b, |, c, d]

不能使用spil分隔"." 和 "|"

1 String[] depotManualDealConfig = strDepotManualDealConfig.split("\\|");
1 String[] depotManualDealConfig = StringUtils.split(strDepotManualDealConfig,"|");

    b.Invalid syntax for regular expression(嚴重)

The code here uses a regular expression that is invalid according to the syntax for regular expressions. This statement will throw a PatternSyntaxException when executed.

非法的正則表達式

1 String regex = "[\\u4E00-\\u9FFF0-9a-zA-Z-—\\\\/#()()]\"), @\"[\\u4E00-\\u9FFF].*";
2         Pattern pattern = Pattern.compile(regex);

 

  8.Suspicious integer expression

    a.Bad comparison of signed byte

Signed bytes can only have a value in the range -128 to 127. Comparing a signed byte with a value outside that range is vacuous and likely to be incorrect. To convert a signed byte b to an unsigned value in the range 0..255, use 0xff & b

byte比較使用錯誤,有符號位比較範圍在-128到127,如果要用無符號位比較用0xff轉換

 1 private static String UrlEncode(String url)
 2     {
 3         byte[] bytes;
 4         try
 5         {
 6             bytes= url.getBytes("UTF-8");
 7         }
 8         catch (Exception ex)
 9         {
10             return null;
11         }
12         int num = bytes.length;
13         StringBuilder stringBuilder = new StringBuilder(num * 3);
14         for (int i = 0; i < num; i++)
15         {
16             if (bytes[i] > -128)
17             {
18                 stringBuilder.append("%");
19                 stringBuilder.append(String.format("%02X", bytes[i]));
20                 i++;
21                 stringBuilder.append("%");
22                 stringBuilder.append(String.format("%02X", bytes[i]));
23             }
24             else
25             {
26                 String result;
27                 try {
28                     result=new String(bytes,"UTF-8");
29                 }
30                 catch (Exception ex)
31                 {
32                     return null;
33                 }
34                 stringBuilder.append(result);
35             }
36         }
37         return stringBuilder.toString();
38     }

 

    b.Bad comparison of nonnegative value with negative constant or zero

This code compares a value that is guaranteed to be non-negative with a negative constant or zero.

不爲負數的值比較使用錯誤

1 if (notExistDepartIdList == null || notExistDepartIdList.size() <== 0) {
2                 String idList = StringUtils.join(notExistDepartIdList, ",");
3                 String errorMsg = String.format("保存失敗,這些點部不存在:%1$s", idList);
4                 return errorMsg;
5             }

 

  9.Useless/non-informative string generated

    a.Invocation of toString on an array(嚴重)

The code invokes toString on an array, which will generate a fairly useless result such as [C@16f0472. Consider using Arrays.toString to convert the array into a readable String that gives the contents of the array. See Programming Puzzlers, chapter 3, puzzle 12.

調用了數組的toString,使用錯誤

 1 private boolean AddValidate(AddAIStationConfigRequest input) {
 2         
 3         int type = input.gettype();
 4         TsAiStationConfig dbEntity = tsAiStationConfigService.Get(input.getname(), type);
 5         if (dbEntity != null && StringUtils.isNotBlank(dbEntity.getId())) {
 6             throw new Exception("版本號已存在");
 7         }
 8 
 9         List<TsAiStationConfig> list = tsAiStationConfigService.GetList(type);
10 
11         if (list != null && !list.isEmpty() && StringUtils.isNotBlank(input.getdepotids())) {
12             String[] inputdepotidArray = input.getdepotids().split(",");
13             List<String> dbDepotIdList = list.parallelStream().map(p -> p.getDepotIds()).collect(Collectors.toList());
14 
15             if (dbDepotIdList != null && !dbDepotIdList.isEmpty() && inputdepotidArray != null) {
16                 for (String depots : dbDepotIdList) {
17 
18                     if(StringUtils.isBlank(depots)) {
19                         continue;
20                     }
21                     
22                     String[] dbList = depots.split(",");
23 
24                     for (String db_depot : dbList) {
25                         if(Arrays.asList(inputdepotidArray).contains(db_depot))
26                         {
27                             throw new Exception("已存在,dbDepotIdList:" + JSONObject.toJSONString(dbDepotIdList));
28                         }
29                         if (inputdepotidArray.toString().contains(db_depot)) {
30                             throw new Exception("已存在,dbDepotIdList:" + JSONObject.toJSONString(dbDepotIdList));
31                         }
32                     }
33                 }
34                 for (String input_depot : inputdepotidArray) {
35                     TsPositionConfig posCfg = positionCachedHelper.IsOpenEntity(input_depot);
36                     if (posCfg == null) {
37                         throw new Exception("未開啓" + input_depot);
38                     }
39                 }
40             }
41         }
42         return true;
43     }

 

  10.Ignored parameter

    a.A parameter is dead upon entry to a method but overwritten

The initial value of this parameter is ignored, and the parameter is overwritten here. This often indicates a mistaken belief that the write to the parameter will be conveyed back to the caller.

參數沒有被使用,但是被重新賦值了,這種

 1 public  GetUseableTrcukModel Get(String depot_id, String carno, int cached)
 2     {
 3         cached = 0;
 4         String key = RedisPrefixKey.ac13 + depot_id;
 5         GetUseableTrcukModel model = null;
 6         if (redisUtils.hHasKey(key, carno))
 7         {
 8             model = (GetUseableTrcukModel)redisUtils.hget(key, carno);
 9             cached = 1;
10         }
11         return model;
12     }

 

  11.Bad casts of object references

    a.Impossible downcast of toArray() result

This code is casting the result of calling toArray() on a collection to a type more specific than Object[], as in:
String[] getAsArray(Collection<String> c) {
return (String[]) c.toArray();
}
This will usually fail by throwing a ClassCastException. The toArray() of almost all collections return an Object[]. They can't really do anything else, since the Collection object has no reference to the declared generic type of the collection.
The correct way to do get an array of a specific type from a collection is to use c.toArray(new String[]); or c.toArray(new String[c.size()]); (the latter is slightly more efficient).
There is one common/known exception exception to this. The toArray() method of lists returned by Arrays.asList(...) will return a covariantly typed array. For example, Arrays.asArray(new String[] { "a" }).toArray() will return a String []. FindBugs attempts to detect and suppress such cases, but may miss some.

數組轉換使用了錯誤的方法

1         String[] carNoLst = (String[])list.stream().map(p -> p.getCarNo()).collect(Collectors.toList()).toArray();
2         String[] carNoLst = list.stream().map(p -> p.getCarNo()).collect(Collectors.toList()).toArray(new String[list.size()]);

 

  12.Unwritten field

    a.Unwritten field

This field is never written.  All reads of it will return the default value. Check for errors (should it have been initialized?), or remove it if it is useless.

屬性沒有使用過,建議去掉

 1 public class UpdateBagStateModel {
 2     /**
 3      * 批次號
 4      * 
 5      */
 6     private String batchno;
 7 
 8     public final String getbatchno() {
 9         return batchno;
10     }
11 
12     public final void setbatchno(String value) {
13         batchno = value;
14     }
15 
16     /**
17      * 運單號
18      * 
19      */
20 //C# TO JAVA CONVERTER TODO TASK: Java annotations will not correspond to .NET attributes:
21     private String waybillno;
22     public final String getwaybillno() {
23         return waybillno;
24     }
25 
26     public final void setwaybillno(String value) {
27         waybillno = value;
28     }
29     
30     private String  operationman;
31     
32     public final String getOperationman()
33     {
34         return  operationman;
35     }
36     
37     
38 }

 

    b.Field only ever set to null

All writes to this field are of the constant value null, and thus all reads of the field will return null. Check for errors, or remove it if it is useless.

屬性曾經設置爲null,看具體代碼,有些類屬性沒用了要去掉或者重新定義成局部變量。

  13.Confusing method name

    a.Very confusing method names

The referenced methods have names that differ only by capitalization. This is very confusing because if the capitalization were identical then one of the methods would override the other.

非常容易迷惑的方法名

1 protected TaAutoScheduleLog.EnumActionCategory getenumActionCategorygetEnumActionCategory()
2     {
3         return TaAutoScheduleLog.EnumActionCategory.ERP;
4     }

 

三 Dodgy code(具有潛在危險的代碼,可能運行期產生錯誤)

  1.Null pointer dereference

    a.Possible null pointer dereference due to return value of called method

The return value from a method is dereferenced without a null check, and the return value of that method is one that should generally be checked for null. This may lead to a NullPointerException when the code is executed.

 1 public static boolean deleteDirectory(String filePath) {
 2         boolean flag = false;
 3         // 如果sPath不以文件分隔符結尾,自動添加文件分隔符
 4         if (!filePath.endsWith(File.separator)) {
 5             filePath = filePath + File.separator;
 6         }
 7         File dirFile = new File(filePath);
 8         // 如果dir對應的文件不存在,或者不是一個目錄,則退出
 9         if (!dirFile.exists() || !dirFile.isDirectory()) {
10             return false;
11         }
12         flag = true;
13         // 刪除文件夾下的所有文件(包括子目錄)
14         File[] files = dirFile.listFiles();
15         if(files!=null) {
16             for (int i = 0; i < files.length; i++) {
17                 // 刪除子文件
18                 if (files[i].isFile()) {
19                     flag = deleteFile(files[i].getAbsolutePath());
20                     if (!flag) {
21                         break;
22                     }
23 
24                 } // 刪除子目錄
25                 else {
26                     flag = deleteDirectory(files[i].getAbsolutePath());
27                     if (!flag) {
28                         break;
29                     }
30 
31                 }
32             }
33         }
34         if (!flag){
35             return false;
36         }
37             
38         // 刪除當前目錄
39         if (dirFile.delete()) {
40             return true;
41         } else {
42             return false;
43         }
44     }

 

    b.Load of known null value

The variable referenced at this point is known to be null due to an earlier check against null. Although this is valid, it might be a mistake (perhaps you intended to refer to a different variable, or perhaps the earlier check to see if the variable is null should have been a check to see if it was non-null).

1         if (entity == null) {
2             throw new RuntimeException("entity == null:ExcuteErpOldDispatch" + entity.getCarNo());
3         }

 

    c.Read of unWritten public or protected field

The program is dereferencing a public or protected field that does not seem to ever have a non-null value written to it. Unless the field is initialized via some mechanism not seen by the analysis, dereferencing this value will generate a null pointer exception.

引用的對象可能永遠爲空,即定義對象的時候就賦值null,這種寫法是危險的。

1 public class BaseVoice
2 {
3     
4     protected TaVoiceMsg mTaVoiceMsg = null;
5     protected MsgContent mMsgContent = null;
6 }

 

  2.RuntimeException capture

    a.Exception is caught when Exception is not thrown

This method uses a try-catch block that catches Exception objects, but Exception is not thrown within the try block, and RuntimeException is not explicitly caught. It is a common bug pattern to say try { ... } catch (Exception e) { something } as a shorthand for catching a number of types of exception each of whose catch blocks is identical, but this construct also accidentally catches RuntimeException as well, masking potential bugs.
A better approach is to either explicitly catch the specific exceptions that are thrown, or to explicitly catch RuntimeException exception, rethrow it, and then catch all non-Runtime Exceptions, as shown below:
try {
...
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
... deal with all non-runtime exceptions ...
}

異常捕獲之後未處理

 1  public static String getPreTime(String sj1, String jj) {
 2     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 3     String mydate1 = "";
 4     try {
 5       Date date1 = format.parse(sj1);
 6       long Time = (date1.getTime() / 1000) + Integer.parseInt(jj) * 60;
 7       date1.setTime(Time * 1000);
 8       mydate1 = format.format(date1);
 9     } catch (Exception e) {
10 //todo
11     }
12     return mydate1;
13   }

 

  3.Bad casts of object references

    a.instanceof will always retrun true

This instanceof test will always return true (unless the value being tested is null). Although this is safe, make sure it isn't an indication of some misunderstanding or some other logic error. If you really want to test the value for being null, perhaps it would be clearer to do better to do a null test rather than an instanceof test.

instanceof判斷永遠爲true

public static String buildKyeApiSignForGet(String accessKey, Map<String, Object> object) {

         if (object instanceof Mapobject!=null) {

            return sortMapForSign((Map<String,Object>)object, accessKey);

        } else {
            throw new RuntimeException("待簽名串類型不符合MAP");
        }

    }

 

  4.Redundant comparison to null

    a.Redundant nullcheck of value known to be non-null

This method contains a redundant check of a known non-null value against the constant null.

 對一個已知不是null的值重複進行空值判斷

1         String dddrivename = (dd == null ? "" : dd.getDD_003());
2             String dddriveid = (dd == null ? "" : dd.getdriverId());
3             String ddcarno = (dd == null ? "" : dd.getDD_004());

 

    b.Redundant nullcheck of value known to be null

This method contains a redundant check of a known null value against the constant null.

 對一個已知是null的值重複進行非空值判斷

1         TaAutoDispatchTask task = null;
2         if (task != null) {
3 }

 

  5.Questionable integer math

    a.Computation of average could overflow

The code computes the average of two integers using either division or signed right shift, and then uses the result as the index of an array. If the values being averaged are very large, this can overflow (resulting in the computation of a negative average). Assuming that the result is intended to be nonnegative, you can use an unsigned right shift instead. In other words, rather that using (low+high)/2, use (low+high) >>> 1
This bug exists in many earlier implementations of binary search and merge sort. Martin Buchholz found and fixed it in the JDK libraries, and Joshua Bloch widely publicized the bug pattern.

計算平均值可能溢出

 1  private int GetClockwiseNearestNode(Integer[] keys, int hashOfItem) {
 2         int begin = 0;
 3         int end = keys.length - 1;
 4 
 5         if (keys[end] < hashOfItem || keys[0] > hashOfItem) {
 6             return 0;
 7         }
 8 
 9         int mid = begin;
10         while ((end - begin) > 1) {
11             mid = (end + begin) / 2;
12             mid=(end&begin)+((end^begin)>>1);
13             if (keys[mid] >= hashOfItem) {
14                 end = mid;
15             } else {
16                 begin = mid;
17             }
18         }
19 
20         return end;
21     }

 

  6.Dead local store

    a.Dead store to loccal variable

This instruction assigns a value to a local variable, but the value is not read or used in any subsequent instruction. Often, this indicates an error, because the value computed is never used.
Note that Sun's javac compiler often generates dead stores for final local variables. Because FindBugs is a bytecode-based tool, there is no easy way to eliminate these false positives.

未用的局部變量,但有可能是誤報

 

  7.Casting from integer values

    a.Result of integer multiplication cast to long

This code performs integer multiply and then converts the result to a long, as in:
long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }
If the multiplication is done using long arithmetic, you can avoid the possibility that the result will overflow. For example, you could fix the above code to:
long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; }
or
static final long MILLISECONDS_PER_DAY = 24L*3600*1000;
long convertDaysToMilliseconds(int days) { return days * MILLISECONDS_PER_DAY; }

整形乘法的結果轉換爲long型

 1 /**
 2    * 得到一個時間延後或前移幾天的時間,nowdate爲時間,delay爲前移或後延的天數
 3    */
 4   public static String getNextDay(String nowdate, String delay) {
 5     try {
 6       SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
 7       String mdate = "";
 8       Date d = strToDate(nowdate);
 9       long myTime = (d.getTime() / 1000) + Integer.parseInt(delay) * 24L * 60 * 60;
10       d.setTime(myTime * 1000);
11       mdate = format.format(d);
12       return mdate;
13     } catch (Exception e) {
14       return "";
15     }
16   }

 

  8.Switch case falls through

    a.Switch statement found where default case is missing

This method contains a switch statement where default case is missing. Usually you need to provide a default case.
Because the analysis only looks at the generated bytecode, this warning can be incorrect triggered if the default case is at the end of the switch statement and the switch statement doesn't contain break statements for other cases.

Switch語句中沒有包含default

 1 switch (params.getType()) {
 2         case 0:
 3             enumType = AutoScheduleBLL_zl.EnumType.waybillno;
 4             break;
 5         case 1:
 6             enumType = AutoScheduleBLL_zl.EnumType.orderno;
 7             break;
 8         case 2:
 9             enumType = AutoScheduleBLL_zl.EnumType.depot;
10             break;
11             default:
12                 break;
13         }

 

  9.Useless code

    a.Useless object created

Our analysis shows that this object is useless. It's created and modified, but its value never go outside of the method or produce any side-effect. Either there is a mistake and object was intended to be used or it can be removed.
This analysis rarely produces false-positives. Common false-positive cases include:
- This object used to implicitly throw some obscure exception.

未使用的對象應刪除掉,不然有可能拋出異常

1 List<Object> vals2 = new ArrayList<>();
2         vals2.add("2018-05-05");
3         vals2.add("2018-05-09");
4         //vo2.setValues(vals2);

 

  10.Misuse of static fields

    a.Write to static field from instance method

This instance method writes to a static field. This is tricky to get correct if multiple instances are being manipulated, and generally bad practice.

靜態對象不要多次實例化

  11.Bad use of return value from method

    a.Return value of method without side effect is ignored

This code calls a method and ignores the return value. However our analysis shows that the method (including its implementations in subclasses if any) does not produce any effect other than return value. Thus this call can be removed.
We are trying to reduce the false positives as much as possible, but in some cases this warning might be wrong. Common false-positive cases include:
- The method is designed to be overridden and produce a side effect in other projects which are out of the scope of the analysis.
- The method is called to trigger the class loading which may have a side effect.
- The method is called just to get some exception.
If you feel that our assumption is incorrect, you can use a @CheckReturnValue annotation to instruct FindBugs that ignoring the return value of this method is acceptable.

未使用的代碼最好去掉

1 public List<TaSubdivisionBag> GetSubByWaybillNo(String listno) {
2         if (listno.length() == 0) {
3             new java.util.ArrayList<TaSubdivisionBag>();
4         }
5 
6         String[] list = listno.split(",");
7         return taSubdivisionBagService.GetSubByWaybillNo(list);
8     }

 

  12.Dubious method used

    a.Thread passed where Runnable expected(嚴重)

A Thread object is passed as a parameter to a method where a Runnable is expected. This is rather unusual, and may indicate a logic error or cause unexpected behavior.

Thread對象作爲參數傳遞給期望Runnable的方法。 這很不尋常,可能表示存在邏輯錯誤或導致意外行爲。

 1     ExecutorService es = Executors.newCachedThreadPool();
 2         
 3         for(TsPositionConfig entity : list) {
 4             es.execute(new Thread(() -> {
 5                 OpenOrClose(entity);
 6             }));
 7             es.execute(new Runnable() {
 8                            @Override
 9                            public void run() {
10                                OpenOrClose(entity);
11                            }
12             });
13         }
14         es.shutdown();    

 

  13.Unwritten field

    a.Unwritten public or protected field

No writes were seen to this public/protected field.  All reads of it will return the default value. Check for errors (should it have been initialized?), or remove it if it is useless.

未被使用的public 或 protected 屬性,

  14.Unread field

    a.Unread public/proected field

This field is never read.  The field is public or protected, so perhaps it is intended to be used with classes not seen as part of the analysis. If not, consider removing it from the class.

未被使用的public 或 protected 屬性

  15.Unused field

    a.Unused public or protected field

This field is never used.  The field is public or protected, so perhaps it is intended to be used with classes not seen as part of the analysis. If not, consider removing it from the class.

未被使用的public 或 protected 屬性

 

四 Experimental(可試驗代碼/有潛在風險代碼,主要是資源回收方面)

  1.Unsatisfied obligation to clean up stream or resource

    a.Method may fail to clean up stream or resource on checked exception

This method may fail to clean up (close, dispose of) a stream, database object, or other resource requiring an explicit cleanup operation.
In general, if a method opens a stream or other resource, the method should use a try/finally block to ensure that the stream or resource is cleaned up before the method returns.
This bug pattern is essentially the same as the OS_OPEN_STREAM and ODR_OPEN_DATABASE_RESOURCE bug patterns, but is based on a different (and hopefully better) static analysis technique. We are interested is getting feedback about the usefulness of this bug pattern. To send feedback, either:
send email to [email protected]
file a bug report: http://findbugs.sourceforge.net/reportingBugs.html
In particular, the false-positive suppression heuristics for this bug pattern have not been extensively tuned, so reports about false positives are helpful to us.
See Weimer and Necula, Finding and Preventing Run-Time Error Handling Mistakes, for a description of the analysis technique.

方法可能因爲checked exception導致清理流或資源失敗

 1 public static String doPost(final Map<String, Object> strParams, final Map<String, File> fileParams) {
 2         HttpURLConnection conn = null;
 3         try {
 4             URL url = new URL(Const.ErpfileUrl);
 5             conn = (HttpURLConnection) url.openConnection();
 6             conn.setRequestMethod("POST");
 7             conn.setReadTimeout(TIME_OUT);
 8             conn.setConnectTimeout(TIME_OUT);
 9             conn.setDoOutput(true);
10             conn.setDoInput(true);
11             conn.setUseCaches(false);// Post 請求不能使用緩存
12             // 設置請求頭參數
13             conn.setRequestProperty("Connection", "Keep-Alive");
14             conn.setRequestProperty("Charset", "UTF-8");
15             conn.setRequestProperty("Content-Type", CONTENT_TYPE + "; boundary=" + BOUNDARY);
16             /**
17              * 請求體
18              */
19             // 上傳參數
20             DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
21             // getStrParams()爲一個
22             dos.writeBytes(getStrParams(strParams).toString());
23             dos.flush();
24 
25             // 文件上傳
26             StringBuilder fileSb = new StringBuilder();
27             for (Map.Entry<String, File> fileEntry : fileParams.entrySet()) {
28                 fileSb.append(PREFIX).append(BOUNDARY).append(LINE_END)
29                         /**
30                          * 這裏重點注意: name裏面的值爲服務端需要的key 只有這個key 纔可以得到對應的文件 filename是文件的名字,包含後綴名的
31                          * 比如:abc.png
32                          */
33                         .append("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileEntry.getKey() + "\"" + LINE_END)
34                         .append("Content-Type: */*" + LINE_END) // 此處的ContentType不同於 請求頭 中Content-Type
35                         .append(LINE_END);// 參數頭設置完以後需要兩個換行,然後纔是參數內容
36                 dos.writeBytes(fileSb.toString());
37                 dos.flush();
38                 InputStream is = new FileInputStream(fileEntry.getValue());
39                 try {
40                     byte[] buffer = new byte[1024];
41                     int len = 0;
42                     while ((len = is.read(buffer)) != -1) {
43                         dos.write(buffer, 0, len);
44                     }
45                 }
46                 catch (Exception ex)
47                 {
48                     ex.printStackTrace();
49                 }
50                 finally {
51                     is.close();
52                 }
53                 dos.writeBytes(LINE_END);
54             }
55             // 請求結束標誌
56             dos.writeBytes(PREFIX + BOUNDARY + PREFIX + LINE_END);
57             dos.flush();
58             dos.close();
59 
60             BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
61             StringBuilder response = new StringBuilder();
62             String line = null;
63             while ((line = reader.readLine()) != null) {
64                 response.append(line);
65             }
66             return response.toString();
67         } catch (Exception e) {
68             e.printStackTrace();
69         } finally {
70             if (conn != null) {
71                 conn.disconnect();
72             }
73         }
74 
75         return "";
76     }

 

    b.Method may fail to clean up stream or resource

This method may fail to clean up (close, dispose of) a stream, database object, or other resource requiring an explicit cleanup operation.
In general, if a method opens a stream or other resource, the method should use a try/finally block to ensure that the stream or resource is cleaned up before the method returns.

需顯示的回收資源

 1     public final void setFilePath(String value) {
 2             FilePath = value;
 3             if (StringUtils.isNotBlank(value)) {
 4                 File file = new File(value);
 5                 if (file.exists()) {
 6                     try {
 7                         InputStream is=new FileInputStream(file);
 8                             this.setStream(is);
 9                             is.close();
10                     } catch (FileNotFoundException e) {
11                         e.printStackTrace();
12                     }
13                     catch (IOException e)
14                     {
15                         e.printStackTrace();
16                     }
17                 }
18             }
19         }

 

 

五 Internationalization(國際化,當對字符串使用upper或lowercase方法,如果是國際的字符串,可能會不恰當的轉換。)

  1.Dubious method used

    a.Reliance on default encoding

Found a call to a method which will perform a byte to String (or String to byte) conversion, and will assume that the default platform encoding is suitable. This will cause the application behaviour to vary between platforms. Use an alternative API and specify a charset name or Charset object explicitly.

不能隨意信任默認字符編碼,應顯示處理

1    public final int Hash(String item) {
2 
3 //ORIGINAL LINE: uint hash = Hash(Encoding.ASCII.GetBytes(item));
4         int hash = Hash(item.getBytes("UTF-8"));
5         return (int)hash;
6     }

 

六 Performance(性能問題代碼,可能導致性能不佳的代碼)

  1.Dubious method used

    a.Method invokes inefficient new String(String) constructor

Using the java.lang.String(String) constructor wastes memory because the object so constructed will be functionally indistinguishable from the String passed as a parameter.  Just use the argument String directly.

方法調用了效率很低的new String(String)構造方法,只需直接使用String

1 String regexUnion = new String("^(130|131|132|155|156|185|186|145|176)[0-9]{8}$");

 

    b.Method invokes inefficient Boolean constructor;use Boolean.valueOf(...) instead

Creating new instances of java.lang.Boolean wastes memory, since Boolean objects are immutable and there are only two useful values of this type.  Use the Boolean.valueOf() method (or Java 1.5 autoboxing) to create Boolean objects instead.

方法調用了低效的Boolean構造方法;使用Boolean.valueOf(...)代替

1 mDebugLog.append("\n").append(String.format("IsTelePhoneVoice:{0}", (new Boolean(mIsTelePhoneVoice)).toString()));
2         mDebugLog.append("\n").append(String.format("IsTelePhoneVoice:{0}", Boolean.valueOf(mIsTelePhoneVoice)));

 

    c.Method invokes inefficient new String() constructor

Creating a new java.lang.String object using the no-argument constructor wastes memory because the object so created will be functionally indistinguishable from the empty string constant "".  Java guarantees that identical string constants will be represented by the same String object.  Therefore, you should just use the empty string constant directly.

使用了new String()

1 tA_RecordsChangeLogBLL.AddUpdateLog(people.getPeopleNo(), new String()"", peopleModelAfter,
2                 TaRecordsChangeLog.EnmuTableType.TB_People.getValue(), "整車業務", "");

 

  2.Inefficient Map Iterator

    a.Inefficient use of keySet iterator instead of entrySet iterator

This method accesses the value of a Map entry, using a key that was retrieved from a keySet iterator. It is more efficient to use an iterator on the entrySet of the map, to avoid the Map.get(key) lookup.

此方法使用從keySet迭代器檢索的鍵訪問Map條目的值。 在map的entrySet上使用迭代器更有效,以避免Map.get(鍵)查找。

  1 public List<GetDriverScoreDetailsModel> GetDriverScoreDetails(GetDriverScoreDetailsRequest request,Out<Integer> rowTotal) {
  2         rowTotal.setData(0);
  3         if ((StringUtils.isBlank(request.getbeg_createtime()) && !StringUtils.isBlank(request.getend_createtime()))
  4                 || (StringUtils.isBlank(request.getend_createtime()) && !StringUtils.isBlank(request.getbeg_createtime()))) {
  5             throw new Exception("開始任務時間和結束任務時間必須同時輸入或同時不輸入!");
  6         }
  7         Date dt_beg_tasktime = null;
  8         try {
  9             dt_beg_tasktime = TimeUtils.format(request.getbeg_createtime(), TimeUtils.YYYY_MM_DD_HH_MM_SS);
 10         } catch (Exception e) {
 11             dt_beg_tasktime = null;
 12         }
 13 
 14         Date dt_end_tasktime = null;
 15         try {
 16             dt_end_tasktime = TimeUtils.format(request.getend_createtime(), TimeUtils.YYYY_MM_DD_HH_MM_SS);
 17         } catch (Exception e) {
 18             dt_end_tasktime = null;
 19         }
 20 
 21         if(StringUtils.isBlank(request.getbeg_createtime()) || StringUtils.isBlank(request.getend_createtime())) {
 22             throw new Exception("開始任務時間或結束任務時間不能爲空!");
 23         }else if ((!StringUtils.isBlank(request.getbeg_createtime()) && dt_beg_tasktime == null)
 24                 || (!StringUtils.isBlank(request.getend_createtime()) && dt_end_tasktime == null)) {
 25             throw new Exception("開始任務時間或結束任務時間格式不正確!");
 26         } else if (dt_beg_tasktime.after(dt_end_tasktime)) {
 27             throw new Exception("開始任務時間不能大於結束任務時間!");
 28         }
 29 
 30 
 31         List<TaDriveScoreDetails> lstDriverScore =taDriveScoreDetailsService.GetDriverScoreDetails(request, rowTotal);
 32         if (lstDriverScore == null) {
 33             return null;
 34         }
 35 
 36         lstDriverScore.stream().filter(d -> d.getIsDel() != null && d.getIsDel().intValue() == 0).collect(Collectors.toList());
 37 
 38         Map<String, List<TaDriveScoreDetails>> detailGroupBy = new HashMap<>();
 39         for (TaDriveScoreDetails scoreDetails : lstDriverScore) {
 40             String key = scoreDetails.getCol002() + "-" + scoreDetails.getCol011() + "-" + scoreDetails.getCol012() + "-" + scoreDetails.getCol003();
 41             List<TaDriveScoreDetails> temp = null;
 42             if (detailGroupBy.containsKey(key)) {
 43                 temp = detailGroupBy.get(key);
 44             } else {
 45                 temp = new ArrayList<>();
 46             }
 47             temp.add(scoreDetails);
 48             detailGroupBy.put(key, temp);
 49         }
 50         List<GetDriverScoreDetailsModel> listModel = new ArrayList<GetDriverScoreDetailsModel>();
 51         Iterator<Map.Entry<String,List<TaDriveScoreDetails>>> it=detailGroupBy.entrySet().iterator();
 52         while (it.hasNext())
 53         {
 54             Map.Entry<String,List<TaDriveScoreDetails>> me=it.next();
 55             String key=me.getKey();
 56             List<TaDriveScoreDetails> list=me.getValue();
 57         for (String key : detailGroupBy.keySet()) {
 58             List<TaDriveScoreDetails> list = detailGroupBy.get(key);
 59             if (list == null || list.size() == 0)
 60                 continue;
 61 
 62             GetDriverScoreDetailsModel model = new GetDriverScoreDetailsModel();
 63             String[] keyarray = key.split("-");
 64             model.setDriver_name(keyarray[0]);
 65             model.setPosition_name(keyarray[1]);
 66             model.setDept(keyarray[2]);
 67             model.setTask_no(keyarray[3]);
 68 
 69             try {
 70                 String taskTime = TimeUtils.parseDateToStr(list.get(0).getCol004(), TimeUtils.YYYY_MM_DD_HH_MM_SS);
 71                 model.setTask_time(taskTime);
 72             } catch (Exception e) {
 73                 model.setTask_time(null);
 74             }
 75 
 76             try {
 77                 String advanceTime = TimeUtils.parseDateToStr(list.get(0).getCol005(), TimeUtils.YYYY_MM_DD_HH_MM_SS);
 78                 model.setSign_time(advanceTime);
 79             } catch (Exception e) {
 80                 model.setSign_time(null);
 81             }
 82 
 83             try {
 84                 String createtime = TimeUtils.parseDateToStr(list.get(0).getCreateTime(), TimeUtils.YYYY_MM_DD_HH_MM_SS);
 85                 model.setCreatetime(createtime);
 86             } catch (Exception e) {
 87                 model.setCreatetime(null);
 88             }
 89             model.setIs_late((list.get(0).getCol007() != null && list.get(0).getCol007().intValue() == 1) ? "是" : "否");
 90 
 91             Map<Integer, DoubleSummaryStatistics> collect = list.stream()
 92                     .collect(Collectors.groupingBy(TaDriveScoreDetails::getCol038, Collectors.summarizingDouble(TaDriveScoreDetails::getCol008)));
 93 
 94             model.setReminder_penalty(collect.get(ScoreType.UrgeScore.code) != null ? collect.get(ScoreType.UrgeScore.code).getSum() + "" : "");
 95             model.setVoice_penalty(collect.get(ScoreType.TelVoiceScore.code) != null ? collect.get(ScoreType.TelVoiceScore.code).getSum() + "" : "");
 96             model.setRefuse_penalty(
 97                     collect.get(ScoreType.RefuseOrderScore.code) != null ? collect.get(ScoreType.RefuseOrderScore.code).getSum() + "" : "");
 98             model.setBelate_penalty(
 99                     collect.get(ScoreType.BeLateVoiceScore.code) != null ? collect.get(ScoreType.BeLateVoiceScore.code).getSum() + "" : "");
100             model.setTimeout_penalty(
101                     collect.get(ScoreType.TimeOutVoiceScore.code) != null ? collect.get(ScoreType.TimeOutVoiceScore.code).getSum() + "" : "");
102 
103             listModel.add(model);
104         }
105         return listModel;
106     }

 

  3.String concatenation in loop using + operator

    a.Method concatenates strings using + in a loop

The method seems to be building a String using concatenation in a loop. In each iteration, the String is converted to a StringBuffer/StringBuilder, appended to, and converted back to a String. This can lead to a cost quadratic in the number of iterations, as the growing string is recopied in each iteration.
Better performance can be obtained by using a StringBuffer (or StringBuilder in Java 1.5) explicitly.
For example:
// This is bad
String s = "";
for (int i = 0; i < field.length; ++i) {
s = s + field[i];
}

// This is better
StringBuffer buf = new StringBuffer();
for (int i = 0; i < field.length; ++i) {
buf.append(field[i]);
}
String s = buf.toString();

loop裏面應該使用StringBuffer替換+號

 1 /**
 2    * 返回一個隨機數
 3    *
 4    * @param i
 5    * @return
 6    */
 7   public static String getRandom(int i) {
 8     Random jjj = new Random();
 9     // int suiJiShu = jjj.nextInt(9);
10     if (i == 0)
11       return "";
12     String jj = "";
13     StringBuffer jj=new StringBuffer();
14     for (int k = 0; k < i; k++) {
15       jj = jj + jjj.nextInt(9);
16       jj.append(jjj.nextInt(9));
17     }
18     return jj;
19   }

 

  4.Questionable Boxing of primitive value

    a.Boxed value is unboxed and then immediately reboxed

A boxed value is unboxed and then immediately reboxed.

裝箱的值被拆箱,然後立刻重新裝箱了(三元運算符兩個分支的返回類型保持一致)

 1 public final TaCustomerCharacter Create(TaMonthProfit profit) {
 2         TaCustomerCharacter customer = new TaCustomerCharacter();
 3         customer.setId(Util.CreateDbGUID());
 4         customer.setCreateTime(new Date());
 5         customer.setLastUpdateTime(new Date());
 6         customer.setCompanyName(profit.getCompanyName());
 7         customer.setCompanyNo(profit.getCompanyNo());
 8         customer.setCol007(profit.getSumProfit());
 9    customer.setCol008(profit.getGoodTimeRate() == 0 ? 100 : profit.getGoodTimeRate() );
10         customer.setCol008(profit.getGoodTimeRate() == 0 ? Double.valueOf(100) : profit.getGoodTimeRate() );
11         customer.setCol009(profit.getThisDayRate() == 0 ?100 : profit.getThisDayRate());
12         customer.setCol009(profit.getThisDayRate() == 0 ? Double.valueOf(100) : profit.getThisDayRate());
13         return customer;
14     }

 

    b.Boxing/unboxing to parse a pimitive

A boxed primitive is created from a String, just to extract the unboxed primitive value. It is more efficient to just call the static parseXXX method.

使用parseXXX效率會更高點

 1 private void GetLogisticsList(Map<String, Object> dic, String url, List<TaLogisticsXd> response) {
 2         String res = OpenApi.request(url, dic);
 3         if (StringUtils.isNotBlank(res)) {
 4             KyeResponse<ResponseResult<LogisticsXDResponseModel>> responseModel = JSONObject.parseObject(res,
 5                     new TypeReference<Response<ResponseResult<LogisticsXDResponseModel>>>() {
 6                     });
 7             if (responseModel.isFail())
 8                 return;
 9             if (responseModel.getData() == null || responseModel.getData().getRows() == null || responseModel.getData().getRows().size() == 0)
10                 return;
11 
12             List<LogisticsXDResponseModel> list = JSON.parseArray(JSON.toJSONString(responseModel.getData().getRows()),LogisticsXDResponseModel.class);
13             for (LogisticsXDResponseModel model : list) {
14                 response.add(LogisticsXDConverter.ToEntity(model));
15             }
16 
17             if (responseModel.getData().getPage() < responseModel.getData().getPageTotal()) {
18                 dic.put("page", Integer.valueOf(dic.get("page") + "") + 1); // 下一頁遞歸
19                 dic.put("page", Integer.parseInt(dic.get("page").toString()) + 1); // 下一頁遞歸
20                 GetLogisticsList(dic, url, response);
21             }
22         }
23     }

 

    c.Methiod allocates a boxed primitive just to call toString

A boxed primitive is allocated just to call toString(). It is more effective to just use the static form of toString which takes the primitive value. So,
Replace...
With this...
new Integer(1).toString()
Integer.toString(1)
new Long(1).toString()
Long.toString(1)
new Float(1.0).toString()
Float.toString(1.0)
new Double(1.0).toString()
Double.toString(1.0)
new Byte(1).toString()
Byte.toString(1)
new Short(1).toString()
Short.toString(1)
new Boolean(true).toString()
Boolean.toString(true)

使用.toString效率更高

1 if ((new Integer(TaExceptionTask.ExceptionType.Refuse.code)).toString()
2             if ((Integer.toString(TaExceptionTask.ExceptionType.Refuse.code))
3                     .equals(verExReq.getExceptionType())) {
4                 status = TaExceptionTask.EnumVerifyStatus.NoPenalty;
5                 iFlag = 2;
6                 logType = 0;
7             } 

 

    d.Method invokes inefficient Number constructor;use static valueOf instead

Using new Integer(int) is guaranteed to always result in a new object whereas Integer.valueOf(int) allows caching of values to be done by the compiler, class library, or JVM. Using of cached values avoids object allocation and the code will be faster.
Values between -128 and 127 are guaranteed to have corresponding cached instances and using valueOf is approximately 3.5 times faster than using constructor. For values outside the constant range the performance of both styles is the same.
Unless the class must be compatible with JVMs predating Java 1.5, use either autoboxing or the valueOf() method when creating instances of Long, Integer, Short, Character, and Byte.

使用new Integer(int)會產生新的對象,使用靜態Integer.valueOf(int)會使用緩存避免對象分配,valueOf更加高效,

1 model.setExceptionStatus(exTask.getExceptionUploadStatus() == 0 ? ""
2                     : (new Integer(exTask.getExceptionUploadStatus()))+"");
3             model.setExceptionStatus(exTask.getExceptionUploadStatus() == 0 ? ""
4                     : (Integer.toString(exTask.getExceptionUploadStatus())));

 

  5.Inner class could be made static

    a.Should be a static inner class

This class is an inner class, but does not use its embedded reference to the object which created it.  This reference makes the instances of the class larger, and may keep the reference to the creator object alive longer than necessary.  If possible, the class should be made static.

應該是一個靜態內部類

 1 private static class IntegerToEnum<T extends IntToEnumConverter> implements Converter<String, T> {
 2 
 3         private final T[] values;
 4 
 5         public IntegerToEnum(Class<T> targetType) {
 6             values = targetType.getEnumConstants();
 7         }
 8 
 9         @Override
10         public T convert(String source) {
11             for (T t : values) {
12                 if (((BaseEnum) t).getValue() == Integer.parseInt(source)) {
13                     return t;
14                 }
15             }
16             return null;
17         }
18     }

 

  6.Unread field should be static

    a.Unread field: should this field be static

This class contains an instance final field that is initialized to a compile-time static value. Consider making the field static.

未讀取的屬性:這個屬性是否應該是static的?

1 private final static String defaultMapperName = "Converter";

 

  7.Unread field

    a.Unread field

This field is never read.  Consider removing it from the class.

未使用的屬性,建議移除

七 Malicious code vulnerability(如果公開會被惡意攻擊的代碼)

  1.Mutable static field

    a.Field isn't final but should be

This static field public but not final, and could be changed by malicious code or by accident from another package. The field could be made final to avoid this vulnerability.

應該使用final修飾

 

    b.Public static method may expose internal representation

A public static method returns a reference to an array that is part of the static state of the class. Any code that calls this method can freely modify the underlying array. One fix is to return a copy of the array.

Public static方法可能因爲返回了一個數組而暴露內部實現,可返回數組克隆

1 private static TaTask.EnumStatus[] privateNoAllowRedo;
2     public static TaTask.EnumStatus[] getNoAllowRedo()
3     {
4         return privateNoAllowRedo.clone();
5     }

 

    c.Field should be package protected

A mutable static field could be changed by malicious code or by accident. The field could be made package protected to avoid this vulnerability.

 屬性應該是package protected

 

    d.Field is a mutable collection

A mutable collection instance is assigned to a final static field, thus can be changed by malicious code or by accident from another package. Consider wrapping this field into Collections.unmodifiableSet/List/Map/etc. to avoid this vulnerability.

如何設置一個static不可變集合,以及非靜態的setter調用靜態的setter方法給靜態成員變量賦值。

 1 public static final java.util.HashMap<String, Integer> ProvinceDicData = new java.util.HashMap<String, Integer>();
 2     static {
 3         ProvinceDicData.put("津", 101);
 4         ProvinceDicData.put("冀", 102);
 5         ProvinceDicData.put("晉", 103);
 6         ProvinceDicData.put("蒙", 104);
 7         ProvinceDicData.put("遼", 105);
 8         ProvinceDicData.put("吉", 106);
 9         ProvinceDicData.put("黑", 107);
10         ProvinceDicData.put("滬", 108);
11         ProvinceDicData.put("蘇", 109);
12         ProvinceDicData.put("浙", 110);
13         ProvinceDicData.put("皖", 111);
14         ProvinceDicData.put("閩", 112);
15         ProvinceDicData.put("贛", 113);
16         ProvinceDicData.put("魯", 114);
17         ProvinceDicData.put("豫", 115);
18         ProvinceDicData.put("鄂", 116);
19         ProvinceDicData.put("湘", 117);
20         ProvinceDicData.put("粵", 118);
21         ProvinceDicData.put("桂", 119);
22         ProvinceDicData.put("瓊", 120);
23         ProvinceDicData.put("渝", 121);
24         ProvinceDicData.put("川", 122);
25         ProvinceDicData.put("貴", 123);
26         ProvinceDicData.put("滇", 124);
27         ProvinceDicData.put("藏", 125);
28         ProvinceDicData.put("陝", 126);
29         ProvinceDicData.put("甘", 127);
30         ProvinceDicData.put("青", 128);
31         ProvinceDicData.put("寧", 129);
32         ProvinceDicData.put("新", 130);
33         ProvinceDicData.put("臺", 131);
34         ProvinceDicData.put("港", 132);
35         ProvinceDicData.put("澳", 133);
36         ProvinceDicData.put("京", 134);
37         ProvinceDicData.put("雲", 135);
38         ProvinceDicData.put("蜀", 136);
39         ProvinceDicData.put("黔", 137);
40         ProvinceDicData.put("秦", 138);
41         ProvinceDicData.put("隴", 139);
42     }
43     public static java.util.Map<String, Integer> ProvinceDicData;
44     public void setProvinceDicData(java.util.Map<String, Integer> map){this.setProvinceDicDataValue(map);}
45     public static void setProvinceDicDataValue(java.util.Map<String, Integer> map)
46     {
47         Const.ProvinceDicData=map;
48     }
49     {
50         java.util.Map<String,Integer> map= Maps.newHashMap();
51         map.put("津", 101);
52         map.put("冀", 102);
53         map.put("晉", 103);
54         map.put("蒙", 104);
55         map.put("遼", 105);
56         map.put("吉", 106);
57         map.put("黑", 107);
58         map.put("滬", 108);
59         map.put("蘇", 109);
60         map.put("浙", 110);
61         map.put("皖", 111);
62         map.put("閩", 112);
63         map.put("贛", 113);
64         map.put("魯", 114);
65         map.put("豫", 115);
66         map.put("鄂", 116);
67         map.put("湘", 117);
68         map.put("粵", 118);
69         map.put("桂", 119);
70         map.put("瓊", 120);
71         map.put("渝", 121);
72         map.put("川", 122);
73         map.put("貴", 123);
74         map.put("滇", 124);
75         map.put("藏", 125);
76         map.put("陝", 126);
77         map.put("甘", 127);
78         map.put("青", 128);
79         map.put("寧", 129);
80         map.put("新", 130);
81         map.put("臺", 131);
82         map.put("港", 132);
83         map.put("澳", 133);
84         map.put("京", 134);
85         map.put("雲", 135);
86         map.put("蜀", 136);
87         map.put("黔", 137);
88         map.put("秦", 138);
89         map.put("隴", 139);
90         this.setProvinceDicData(Collections.unmodifiableMap(map));
91     }

 

    e.Field is a mutable collection which should be package protected

A mutable collection instance is assigned to a final static field, thus can be changed by malicious code or by accident from another package. The field could be made package protected to avoid this vulnerability. Alternatively you may wrap this field into Collections.unmodifiableSet/List/Map/etc. to avoid this vulnerability.

與d一致處理

  2.Storing reference to mutable object

    a.May expose internal representation by incorporating reference to mutable object(嚴重)

This code stores a reference to an externally mutable object into the internal representation of the object.  If instances are accessed by untrusted code, and unchecked changes to the mutable object would compromise security or other important properties, you will need to do something different. Storing a copy of the object is better approach in many situations.

此代碼將對外部可變對象的引用存儲到對象的內部表示中。即外部代碼值改變會引起對象值改變,涉及到引用傳遞值的問題。

測試代碼:

1         LogisticsXDDispatchMessage2 logisticsXDDispatchMessage2=new LogisticsXDDispatchMessage2();
2         java.util.Date dt= new java.util.Date();
3         logisticsXDDispatchMessage2.setOrderTime(dt);
4         System.out.printf(logisticsXDDispatchMessage2.getOrderTime().toString()+"%n");
5         dt.setMonth(1);
6         System.out.printf(logisticsXDDispatchMessage2.getOrderTime().toString());

輸出:

1 Fri Apr 19 16:01:18 CST 2019
2 Tue Feb 19 16:01:18 CST 2019
 1 public class LogisticsXDDispatchMessage2 implements Serializable {
 2         @JsonFormat(pattern="yyyy-MM-dd HH:mm:dd")
 3         private Date orderTime;
 4         public void setOrderTime(Date orderTime) {
 5              this.orderTime = (Date) orderTime.clone();
 6          }
 7          public Date getOrderTime() {
 8              return (Date) orderTime.clone();
 9          }
10 }

 

  3.Method returning array may expose internal representation

    a.May expose internal representation by returning reference to mutable object

Returning a reference to a mutable object value stored in one of the object's fields exposes the internal representation of the object.  If instances are accessed by untrusted code, and unchecked changes to the mutable object would compromise security or other important properties, you will need to do something different. Returning a new copy of the object is better approach in many situations.

同2處理方式一致

 

參考:https://my.oschina.net/bairrfhoinn/blog/156200

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