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

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