GVKun编程网logo

findbugs和数据库密码安全性问题(数据库中的访问密钥和安全锁)

12

最近很多小伙伴都在问findbugs和数据库密码安全性问题和数据库中的访问密钥和安全锁这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展2.findbugs总结、Debian11.2

最近很多小伙伴都在问findbugs和数据库密码安全性问题数据库中的访问密钥和安全锁这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展2.findbugs 总结、Debian 11.2 发布,修复 Bug 及安全性问题、findbugs、FindBugs 2.0.1 RC3 发布等相关知识,下面开始了哦!

本文目录一览:

findbugs和数据库密码安全性问题(数据库中的访问密钥和安全锁)

findbugs和数据库密码安全性问题(数据库中的访问密钥和安全锁)

我正在使用以下代码初始化数据库连接:

 public Connection getConnection() {        try {            if (null == connection) {                String driverName = "com.mysql.jdbc.Driver"; // MySQL MM JDBC driver                Class.forName(driverName);                // Create a connection to the database                String serverName = "localhost";                String database = "database";                String url = "jdbc:mysql://" + serverName + "/" + mydatabase; // a JDBC url                String username = "username";                String password = "password";                connection = DriverManager.getConnection(url, username, password);            }            return connection;        } catch (ClassNotFoundException cnfe) {            cnfe.printStackTrace();        } catch (SQLException sqle) {            sqle.printStackTrace();        }        throw new NullPointerException("Cannot establish database connection...");    }

而且我知道这样做是不好的做法,而且我还FindBugs违反了代码,并遇到了如下安全问题: This code creates a databaseconnect using a hardcoded, constant password. Anyone with access to either thesource code or the compiled code can easily learn the password.

在没有此安全漏洞的情况下初始化数据库连接的最佳方法是什么?

答案1

小编典典

绝大多数Web应用程序都使用硬编码的用户名/密码进行SQL连接。通常不赞成将生产凭证检查到源代码控制中,或者赋予实习生删除生产数据库的能力。生产凭证应受到保护,只有特权员工才能访问它们。

Web应用程序通常会泄漏其配置文件。例如,如果.xml文件存储在webroot中,则可以远程访问它:http://localhost/configs/db_config.xml

通常的做法是禁止访问数据库(对于mysql,阻止tcp端口3306)。实际上,这是PCI-DSS的要求。即使要获取用户名和密码,也将毫无用处。

2.findbugs 总结

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 findbugs@cs.umd.edu
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

Debian 11.2 发布,修复 Bug 及安全性问题

Debian 11.2 发布,修复 Bug 及安全性问题

Debian 11.2 发布了,作为 Debian 11 “Bullseye” 的第二个版本,它带来了一系列的 bug 修复和安全问题的完善,其中最为引人注目的更新项,是对沸沸扬扬的 “Log4j 漏洞” 问题的修复:DSA-5020 、DSA-5022 。

除此之外,此版本还有大量安全相关内容,如对 curl 的 “从 curl-config 中删除 - file-prefix-map,以修复 libcurl4-gnutls-dev 在 multiarch 下的可协同安装性”,如 wget  的” 修复 wget ,以处理 32 位系统上超过 2GB 的下载”,以及其他...

完整版的更新列表可在公告原文中查看。

findbugs

findbugs

findbugs 错误总结

 本篇是从别人那找到的,为了让我回头查看 findbugs 错误怎么解决而保存的

有很多问题其实挺隐晦的,比如第三条。还有人会使用 == 来判断常量字符串和 String 类型是否相等,这个就是基础不牢的缘故了。

记得把 findbugs 尽量清零哦。

1.       NP_NULL_ON_SOME_PATH_EXCEPTION

 

类型

必改项

描述

A  reference value which is null on some  exception control path is dereferenced here.  This may lead to aNullPointerException when the code is executed.  Note that because FindBugs  currently does not prune infeasible exception paths, this may be a false  warning.

 

代码调用时,遇到异常分支,可能造成一个对象没有获得赋值依旧保持 NULL 空指针。接下来如果对这个对象有引用,可能造成 NullPointerException 空指针异常。

案例

private voidtest_NP_NULL_ON_SOME_PATH_EXCEPTION(String name, String

pass){

User user = null;

int nport = 10;

try{

user = checkUser(name, pass);

if (user == null){

System.out.println(" 密码错误 ");

close();

return ;

}

}

catch (SQLException e){

         e.printStackTrace();

}

user.setPort(nport); // 这端代码有 NP_NULL_ON_SOME_PATH_EXCEPTION

}

代码分析:这里 User 对象是在 try 块中赋值的, 但是由于 checkUser 方法赋值失败造成异常,导致 User 对象为空后, 直接转入异常处理模块执行 e.printStackTrace(); 此时并没有返回,接下来执行 user.setPort(nport) 时, 必然造成空指针。

 

案例二:

md = null;  

try {  

    md = MessageDigest.getInstance("SHA-256");  

    md.update(bt);  

   } catch (NoSuchAlgorithmException e) {  

    e.printStackTrace();// script1    

   }  

   byte[] digest = md.digest();// script2  

解决方法

案例一:根据代码逻辑实际情况采取解决方法, 在异常情况下考虑好分支路径

 

案例二:bug 出现在 script2 处,在 script1 处处理相应的 exception 即可,如 throwreturn

 

2.       NP_NULL_ON_SOME_PATH

 

类型

必改项

描述

There  is a branch of statement that,if executed, guarantees that a null  value will be dereferenced, which would generate aNullPointerException 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.

 

对象可能没有重新赋值

案例

 

如在 JDBC 编程时候,在关闭 ResultSet 时候 (rs.close()),经常会出现这个 bug

 

解决方法

解决办法很容易想到,判断是否为 null

使用 try...catch...finally

 

 

3.       EC_UNRELATED_CLASS_AND_INTERFACE

 

类型

必改项

描述

This  method calls equals(Object) on two references, one of which is a class and  the other an interface, where neither the class nor any of its non-abstract  subclasses implement the interface. Therefore, the objects being compared are  unlikely to be members of the same class at runtime (unless some application  classes were not analyzed, or dynamic class loading can occur at runtime).  According to the contract of equals(), objects of different classes should  always compare as unequal; therefore, according to the contract defined by  java.lang.Object.equals(Object), the result of this comparison will always be  false at runtime.

 

使用 equals 方法比较不相关的类和接口

案例

StringBuilder  builder = new StringBuilder"nihao";

String  string = "nihao";

builder.equalsstring;

 

解决方法

调用 equals() 比较不同的类型。

此方法调用相当于两个不同的类类型的引用,没有共同的子类(对象)。

因此,所比较的对象是不太可能在运行时相同的类成员(除非一些

应用类没有分析或动态类加载可以发生在运行时)。据

equals() 的规则,不同类的对象应始终比较不平等,因此,根据

java.lang.Object.equals 定义的合同(对象),FALSE 将永远是比较的结果

在运行时错误。

 

 

4.       UG_SYNC_SET_UNSYNC_GET

 

类型

必改项

描述

This  class contains similarly-named get and set methods where the set method is  synchronized and the get method is not.  This may result in incorrect  behavior at runtime, as callers of the get method will not necessarily see a  consistent state for the object.  The get method should be made  synchronized.

 

这个类包含类似命名的 get set 方法。在 set 方法是同步方法和 get 方法是非同步方法。这可能会导致在运行时的不正确行为,因为调用的 get 方法不一定返回对象一致状态。 GET 方法应该同步。

案例

 

 

解决方法

 

 

 

5.       DLS_DEAD_LOCAL_STORE

 

类型

必改项

描述

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.

该指令为局部变量赋值,但在其后的没有对她做任何使用。通常,这表明一个错误,因为值从未使用过。

案例

 

案例二:

String  abc = "abc"; 

String  xyz = new String(""); 

xyz =  abc; 

System.out.println(xyz);

解决方法

删除未使用的本地变量

案例二:

因为 String xyz = new String("");

  这一句执行 3 个动作:  

  1) 创建一个引用 xyz  

  2) 创建一个 String 对象  

  3) String 的引用赋值给 xyz

  其中,后面两个动作是多余的,因为后面的程序中你没有使用这个新建的 String 对象,而是重新给 xyz 赋值, 

xyz =  abc; 所以,只需要 String  xyz = abc; 就可以了

 

6.       RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE

 

类型

选改项

描述

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.

 

案例

出现该 bug 有两种情况:多余的 null 检查;前边没有 null 值检查的。

比如:我们经常会这个使用 ActionForm

String  clazzId = request.getParameter("clazzId");// script1

studentForm.setClazzID(clazzId);//  script2

往往会在 script2 会出现该错误,因为在 script1 处未检查 clazzId 是否为 null 才导致的。

修改为:

if(clazzId  != null) {

studentForm.setClazzID(clazzId);

}

 

解决方法

在设置使用 clazzId 之前先判断其是否为 null

 

 

7.       ES_COMPARING_STRINGS_WITH_EQ

 

类型

必改项

描述

This  code comparesjava.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 theequals(Object) method  instead.

 

== 或者!= 去比较 String 类型的对象

案例

String  str1 = "java";

String  str2 = "java";

System.out.printstr1==str2;

成果:true(二者都为常量)

String  str1 = new String"java";

String  str2 = new String"java";

System.out.printstr1==str2;

成果:false(二者为对象)

String  str1 = "java";

String  str2 = "blog";

String  s = str1+str2;

System.out.prints=="javablog";

成果:falses 不为常量,为对象)

String  s1 = "java";

String  s2 = new String"java";

System.out.prints1.intern()==s2.intern());

成果:true

 

解决方法

String 对象进行比较的时候:只有两种情况可以使用 == or !=,这两种情况是;仅当两个字符串在源文件中都是常量或者是调用 String.intern() 方法,使用 String 的规范化表示形式来进行比较 , 如果不是这两中情况的话推荐使用.equals(object) 方式

 

 

 

8.       NP_NULL_PARAM_DEREF

 

类型

必改项

描述

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

这种方法调用传递一个空值给非空参数。,要这个参明确注释它是非空参数,要么经过分析得出它总是会被引用不可能为空。

 

案例

int  FunctionOneint xint y=0int z=0int w=0);

我们要给 z 传递整型值 8,作如下调用:

FunctionOne8);

显然,编译器无法确定这个 8 到底要传递给哪个参数。为了达到我们的目的,必须这样调用:

FunctionOne008);

这是 x 被传递了 0y 被传递了 0z 被传递了 8

 

解决方法

我们可以赋予函数参数默认值。

所谓默认值就是在调用时,可以不写某些参数的值,编译器会自动把默认值传递给调用语句中。默认值一般在函数声明中设置;

 

 

9.       UWF_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.

 

此字段是永远不会写入值。所有读取将返回默认值。检查错误(如果它被初始化?),如果它确实没有用就删除掉。

案例

 

 

解决方法

 

 

 

10.  NP_TOSTRING_COULD_RETURN_NULL

 

类型

必改项

描述

This toString  method seems to return null in some circumstances. A liberal reading of the  spec could be interpreted as allowing this, but it is probably a bad idea and  could cause other code to break. Return the empty string or some other  appropriate string rather than null.

toString 方法可能返回 null

案例

 

 

解决方法

 

 

 

11.  MF_CLASS_MASKS_FIELD

 

类型

必改项

描述

This  class defines a field with the same name as a visible instance field in a  superclass. This is confusing, and may indicate an error if methods update or  access one of the fields when they wanted the other.

 

子类中定义了和父类中同名的字段。在调用时会出错

案例

 

 

解决方法

 

 

 

12.  NS_DANGEROUS_NON_SHORT_CIRCUIT

 

类型

必改项

描述

This code  seems to be using non-short-circuit logic (e.g., & or |) rather than  short-circuit logic (&& or ||). In addition, it seem possible that,  depending on the value of the left hand side, you might not want to evaluate  the right hand side (because it would have side effects, could cause an  exception or could be expensive.

Non-short-circuit  logic causes both sides of the expression to be evaluated even when the  result can be inferred from knowing the left-hand side. This can be less  efficient and can result in errors if the left-hand side guards cases when  evaluating the right-hand side can generate an error.

See theJava Language Specification for details

代码中使用(& or |)代替(&& or ||)操作,这会造成潜在的危险

案例

 

缺陷详解:解释一下短路与非短路的区别:

1)短路运算(short-circuit

逻辑与(&&):如果左操作数结果为 true,则继续计算右操作数;如果左操作数结果为 false

,则对右操作数的运算已经没有必要,直接返回结果 false,忽略右操作运算。

逻辑或(||):如果左操作数结果为 false,则继续计算右操作数;如果左操作数结果为 true

,则对右操作数的运算已经没有必要,直接返回结果 true,忽略右操作运算。

正确地使用短路运算符,就可以写出节省时间、提高效率的代码。

2)非短路运算(non-short-circuit

逻辑与(&)、逻辑或(|):不管左操作数的运算结果如何,都一律计算右边的操作数。

我们回放的代码使用的是非短路与(&),也就是不管左边的 sr !=null

的结果如何,都一律运算右边的 sr.getInt(0) == 0,那如果遇到 sr null

值的情况,则一样也会调用到 sr.getInt(0),显然就会出现空指针异常。

解决方法

解决这个问题的最好选择是改用短路运算与(&&)。

SysDataSet sds =  con.csCommonSP("P_KMS_GETORIGINALFILETREE");

SysRecord sr = sds  != null ? sds.getParamSet() : null;

rs = (sr != null&& sr.getInt(0) == 0) ?  sds.getResultSet() :null;

 

 

13.  HE_EQUALS_USE_HASHCODE

 

类型

必改项

描述

This class  overrides equals(Object), but does not override hashCode(), and inherits the  implementation of hashCode() from java.lang.Object (which returns the identity  hash code, an arbitrary value assigned to the object by the VM).   Therefore, the class is very likely to violate the invariant that equal  objects must have equal hashcodes.

If you  don''t think instances of this class will ever be inserted into a HashMap/HashTable,  the recommended hashCode implementation to use is:

public int hashCode() {

  assert false :  "hashCode not designed";

  return 42; // any  arbitrary constant will do

  }

 

一个类覆写了 equals 方法,没有覆写 hashCode 方法,使用了 Object 对象的 hashCode 方法

案例

 

 

 

解决方法

 

 

 

14.  NP_EQUALS_SHOULD_HANDLE_NULL_ARGUMENT

 

类型

必改项

描述

This  implementation of equals(Object) violates the contract defined by  java.lang.Object.equals() because it does not check for null being passed as  the argument. All equals() methods should return false if passed a null  value.

 

变量调用 equals 方法时没有进行是否为 null 的判断

案例

 

 

解决方法

 

 

 

15.  SE_BAD_FIELD

 

类型

必改项

描述

This  Serializable class defines a non-primitive instance field which is neither  transient, Serializable, orjava.lang.Object, and does not appear  to implement theExternalizable interface or thereadObject() andwriteObject() methods.  Objects of this class will not be deserialized  correctly if a non-Serializable object is stored in this field.

 

序列化的类定义了一个非原生实例对象,这个对象是不可序列化的或非 java 对象,而且没有添加 transient 关键字,没有实现 Externalizable 接口或没有添加 readObject() writeObject() 方法,那么这个类的对象将不能正确的反序列化。

 

案例

示例代码:

publicclassMytest implements Serializable {

    private ThreadmThread;

    protected FileOutputStreamoutputStream ;

    // 这两个变量会提示 defines  non-transient non-serializable instance field finoutStream

    private Stringstr;

    private Stringstr1;

    privateinti;

 

}

 

解决方法

解决方法:

1:给对象加上 transient 关键字,对该象将不会被序列化保存和恢复。

publicclassMytest implements Serializable{

    privatetransient ThreadmThread;

    protectedtransient FileOutputStreamoutputStream;

    private Stringstr;

private Stringstr1;

    privateinti;

}

2:实现 Externalizable 接口代替 Serializable 接口,对序列化过程进行完全自主控制。Externalizable 没有默认序列化机制,我们需要在 writeExternal() 方法中将希望被序列化的对象的信息写入,在 readExternal() 中将其恢复,并且 writeObject() 方法与 readObject() 方法中保存和恢复对象的顺序必须相同。

publicclass Mytestimplements Externalizable{

    private ThreadmThread;

    protected FileOutputStreamfoutputStream;

    private Stringstr;

    private Stringstr1;

    privateinti;

    @Override

    publicvoid readExternal(ObjectInput  arg0)throws IOException,

           ClassNotFoundException {

       str=(String) arg0.readObject();

       str1=(String) arg0.readObject();

       i= arg0.readInt();

    }

    @Override

publicvoid  writeExternal(ObjectOutput arg0)throws IOException{

       arg0.writeObject(str);

       arg0.writeObject(str1);

       arg0.writeInt(i);

    }

}

3:添加 writeObject() readObject() 方法替代 Externalizable,对序列化过程进行自主控制。注意是添加 不是复写实现,类型必须为 private,同样 writeObject() 方法与 readObject() 方法中保存和恢复对象的顺序必须相同。

publicclassMytest implements Serializable{

    private ThreadmThread;

    protected FileOutputStreamfoutputStream;

    private Stringstr;

    private Stringstr1;

    privateinti;

    privatevoid  writeObject(ObjectOutputStream outputStream)throws IOException {

       outputStream.writeObject(str);

       outputStream.writeObject(str1);

       outputStream.writeInt(i);

    }  

    privatevoid readObject(ObjectInputStream  inputStream)throws IOException,ClassNotFoundException {

       str=(String) inputStream.readObject();

       str1=(String) inputStream.readObject();

       i= inputStream.readInt();

    }

}

 

16.  NP_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.

 

程序中引用一变量,没有一个可见的机制将一个非空的值赋给它,引用时需要对其进行判断(是否有一不可见的机制对其进行了初始化)不然会空指针异常。

案例

privatestaticArrayList<String> paramList =null;

publicArrayList checkValue(String str1) {

    paramList.clear();

    returnparamList;

}

// 调用 clear() 只是清除 list 内容并不会使 list 报空指针异常,但是 list null 时,就会报空指针异常了。

解决方法

引用前进行判空

privatestatic ArrayList<String>paramList =null;

publicArrayList checkValue(String str1) {

    if (null!=paramList) {          

        paramList.clear();

    }

    returnparamList;

}

 

 

17.  UWF_NULL_FIELD

 

类型

必改项

描述

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 值,所有读取该字段的值都为 null。检查错误,如果它确实没有用就删除掉。

案例

privatestatic ArrayList<String>paramList =null;

public ArrayList<String> returnList(ArrayList  mList) { 

       returnmList;         

}

注:程序中无其函数对 paramList 进行赋值,或一直赋 null 值。

解决方法

1、对 paramList 进行正确赋值。

2、如果 paramList 没有用就删掉。

 

18.  IM_BAD_CHECK_FOR_ODD

 

类型

必改项

描述

The  code uses x % 2 == 1 to check to see if a value is odd, but this won''t work  for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to  check for oddness, consider using x & 1 == 1, or x % 2 != 0.

 

如果使用代码 x % 2  == 1 来检查值是否为奇数,对于负数是无效的,应该使用 x&1==1 x%2!=0

案例

publicboolean isOddness(int value){

    boolean result =false;

        if ((value % 2)  ==1) {

       result = true;

    }

    return result;

    }

分析:如果传进来的 value 是负数则此函数返回的结果是错误的。

解决方法

publicboolean isOddness(int value){

    boolean result =false;

    if ((value & 1)  ==1) {

       result = true;

    }

    return result;

    }

 

 

19.  NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE

 

类型

必改项

描述

There  is a branch of statement that,if executed, guarantees that a null  value will be dereferenced, which would generate aNullPointerException 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. Due  to the fact that this value had been previously tested for nullness, this is  a definite possibility.

 

有一个分支如果进入的话,里面的某些变量可能会是空指针

案例

publicstaticvoid main(String[] args) {

    String  s1 = null;

    String  s2 = "";

    doCompare(s1,  s2);

    }

   

    publicstaticint doCompare(String s1, String s2) {

    int result;

    if (s1 ==null && s2 == null) {

        result  = 0;

    } elseif (s1 ==null && s2 != null) {

        result  = -1;

    } elseif (s1 !=null && s2 == null) {

        result  = 1;

    } else {// s1 != null && s2 != null

        result  = s1.compareTo(s2);

// 这里 s1 可能发生空指针异常,但是此语句不会执行。

    }

    return result;

    }

解决方法

publicstaticint doCompare(String s1, String s2) {

    int result;

    if (s1 ==null && s2 == null) {

        result  = 0;

    } elseif (s1 ==null) {

        assert s2 !=null;

        result  = -1;

    } elseif (s2 ==null) {

        assert s1 !=null;

        result  = 1;

    } else {

        result  = s1.compareTo(s2);

    }

    return result;

    }

 

 

20.  RV_EXCEPTION_NOT_THROWN

 

类型

必改项

描述

This code  creates an exception (or error) object, but doesn''t do anything with it. For  example, something like

if (x < 0)

  new IllegalArgumentException("x must be nonnegative");

It was probably  the intent of the programmer to throw the created exception:

if (x < 0)

  throw new IllegalArgumentException("x must be nonnegative");

 

此代码创建一个异常(或错误)的对象,但不会用它做任何事情。例如:if (x < 0)

 new IllegalArgumentException("x must  be nonnegative");

这可能是程序员的意图抛出创建的异常:

if (x < 0)

 throw new IllegalArgumentException("x  must be nonnegative");

 

案例

privatevoid test(){

new  IllegalArgumentException("x must be  nonnegative");

    }

解决方法

1、打印异常调用栈。

privatevoid test(){

    if(x<0){

new IllegalArgumentException("x must be nonnegative "). printStackTrace();

}

    }

2、抛出异常。

privatevoid test(){

if(x<0){

throw new IllegalArgumentException("x must be nonnegative ");

}

}

 

 

21.  DL_SYNCHRONIZATION_ON_BOOLEAN

 

类型

必改项

描述

The code  synchronizes on a boxed primitive constant, such as an Boolean.

private static Boolean inited = Boolean.FALSE;

...

  synchronized(inited) {

    if (!inited) {

       init();

       inited = Boolean.TRUE;

       }

     }

...

Since there  normally exist only two Boolean objects, this code could be synchronizing on  the same object as other, unrelated code, leading to unresponsiveness and  possible deadlock

该代码同步一个封装的原始常量,例如一个 Boolean 类型。

private static Boolean inited = Boolean.FALSE;

...

  synchronized(inited) {

   if  (!inited) {

      init();

      inited  = Boolean.TRUE;

      }

    }

...

由于通常只存在两个布尔对象,此代码可能是同步的其他无关的代码中相同的对象,这时会导致反应迟钝和可能死锁

 

案例

 

解决方法

 

 

 

22.  ES_COMPARING_PARAMETER_STRING_WITH_EQ

 

类型

必改项

描述

This  code compares ajava.lang.String parameter for reference equality using the == or != operators.  Requiring callers to pass only String constants or interned strings to a  method is unnecessarily fragile, and rarely leads to measurable performance  gains. Consider using theequals(Object) method instead.

 

== 或者 != 方法去比较 String 类型的参数

案例

 

解决方法

 

 

 

23.  JLM_JSR166_UTILCONCURRENT_MONITORENTER

 

类型

必改项

描述

This method performs synchronization an  object that is an instance of a class from the java.util.concurrent package  (or its subclasses). Instances of these classes have their own concurrency  control mechanisms that are orthogonal to the synchronization provided by the  Java keyword synchronized. For example, synchronizing on an AtomicBoolean  will not prevent other threads from modifying the AtomicBoolean.

Such code may be correct, but should be  carefully reviewed and documented, and may confuse people who have to  maintain the code at a later date.

 

 

案例

 

解决方法

 

 

 

24.  DL_SYNCHRONIZATION_ON_SHARED_CONSTANT

 

类型

必改项

描述

The code synchronizes on interned String.

private static String LOCK =  "LOCK";

...

   synchronized(LOCK) { ...}

...

Constant Strings are interned and shared  across all other classes loaded by the JVM. Thus, this could is locking on  something that other code might also be locking. This could result in very  strange and hard to diagnose blocking and deadlock behavior. See http://www.javalobby.org/java/forums/t96352.html andhttp://jira.codehaus.org/browse/JETTY-352.

See CERTCON08-J. Do not synchronize on objects that  may be reused for more information.

 

同步 String 类型的常量时,由于它被 JVM 中多个其他的对象所共有,这样在其他代码中会引起死锁。

案例

 

解决方法

 

 

 

25.  SP_SPIN_ON_FIELD

 

类型

必改项

描述

This  method spins in a loop which reads a field.  The compiler may legally  hoist the read out of the loop, turning the code into an infinite loop.   The class should be changed so it uses proper synchronization (including wait  and notify calls).

 

方法无限循环读取一个字段。编译器可合法悬挂宣读循环,变成一个无限循环的代码。这个类应该改变,所以使用适当的同步(包括等待和通知要求)

案例

 

解决方法

 

 

 

26.  RpC_REPEATED_CONDITIONAL_TEST

 

类型

必改项

描述

The  code contains a conditional test is performed twice, one right after the  other (e.g.,x == 0 ||  x == 0). Perhaps the second occurrence is  intended to be something else (e.g.,x == 0 || y == 0).

 

该代码包含对同一个条件试验了两次,两边完全一样例如:(如 X == 0 | | x == 0)。可能第二次出现是打算判断别的不同条件(如 X == 0 | | y== 0)。

案例

 

解决方法

 

 

 

27.  NP_GUARANTEED_DEREF

 

类型

必改项

描述

There is a statement or branch 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).

Note that a check such as if (x == null)  throw new NullPointerException();x.

 

在正常的 null 判断分支上,对象去除引用操作是受保护的不允许的

案例

public void test()  {
  String var = "";
  int index = 2;
  if (index == -1) {
  var = String.class.getName();
  if (var.length() == 0) {
  var = null;
  }
  } else {
  var = Integer.class.getName();
  if (var.length() == 0) {
  var = null;
  }
  }
  if (var == null) {// FINBUGS reports on this line NP_GUARANTEED_DEREF
  /*
  * There is a statement or branch 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).
  */
  throw new NullPointerException("NULL");
  }
  }

 

解决方法

据说改为 throw new RuntimeException 就会消除警告

去掉 throw new NullPointerException 也可以

 

28.  UR_UNINIT_READ

 

类型

必改项

描述

This  constructor reads a field which has not yet been assigned a value.  This  is often caused when the programmer mistakenly uses the field instead of one  of the constructor''s parameters.

 

此构造方法中使用了一个尚未赋值的字段或属性。

 

案例

String a;

public FindBugsTest(String b) {

    String abc = a; // UR_UNINIT_READ , b 误写为 a

    System.out.println(abc);

}

解决方法

使用函数的参数或初始化的字段

 

29.  NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE

 

类型

必改项

描述

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 aNullPointerException when the code is executed.

 

方法的返回值没有进行是否为空的检查就重新赋值,这样可能会出现空指针异常。

案例

publicvoid caller(int a) {

       String c = called(a);

       if (c.equals("")) { //c maybe null

       } elseif (c.equals("")) {

       }

    }

 

解决方法

增加对返回值是否为空的判断

 

30.  IL_INFINITE_RECURSIVE_LOOP

 

类型

必改项

描述

This  method unconditionally invokes itself. This would seem to indicate an  infinite recursive loop that will result in a stack overflow.

 

案例

public void foo() {

foo();  //  IL_INFINITE_RECURSIVE_LOOP

       //...

}

 

解决方法

避免函数的递归调用,或加上结束递归的条件判断

 

31.  IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_

OUTER_METHOD

 

类型

必改项

描述

An  inner class is invoking a method that could be resolved to either a inherited  method or a method defined in an outer class. By the Java semantics, it will  be resolved to invoke the inherited method, but this may not be want you  intend. If you really intend to invoke the inherited method, invoke it by  invoking the method on super (e.g., invoke super.foo(17)), and thus it will  be clear to other readers of your code and to FindBugs that you want to  invoke the inherited method, not the method in the outer class.

 

 

案例

public void onOK() {

    }

   

    protected  class parentClass {

        public  void onOK() {

    }

    }

   

    protected  class childClass extends parentClass {

       

        public  void callOnOK() {

            onOK();   //IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_OUTER_METHOD, should be super.onOK

        }

       

    }

 

解决方法

如果要引用外部类对象,可以加上 “outclass.this”

如果要引用父类的 onOK 方法,请使用 super.onOK()

 

32.  IP_PARAMETER_IS_DEAD_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.

 

传入参数的值被忽略,但是对传入值进行了修改,并返回给了调用者

案例

publicvoid foo(String p) {

    p = "abc"; //  IP_PARAMETER_IS_DEAD_BUT_OVERWRITTEN

}

 

解决方法

不要将函数的参数作为工作变量

 

33.  FE_FLOATING_POINT_EQUALITY

 

类型

必改项

描述

This  operation compares two floating point values for equality. Because floating  point calculations may involve rounding, calculated float and double values  may not be accurate. For values that must be precise, such as monetary  values, consider using a fixed-precision type such as BigDecimal. For values  that need not be precise, consider comparing for equality within some range,  for example:if (  Math.abs(x - y) < .0000001 ). See the Java  Language Specification, section 4.2.4.

 

此操作比较两个浮点值是否相等。由于浮点运算可能会涉及到舍入,计算 float double 值可能不准确。如果要求值必须准确,如货币值,可以考虑使用固定精度类型,如 BigDecimal 类型的值来比较

案例

 

解决方法

 

 

 

34.  NP_ALWAYS_NULL

 

类型

必改项

描述

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

 

对象赋为 null 值后没有被重新赋值

案例

 

解决方法

 

 

 

35.  DLS_DEAD_LOCAL_STORE_OF_NULL

 

类型

必改项

描述

The  code stores null into a local variable, and the stored value is not read.  This store may have been introduced to assist the garbage collector, but as  of Java SE 6.0, this is no longer needed or useful.

 

把一个本地变量赋值为 null 值,并且再也没有对这个变量做任何的操作。这样可能是为了垃圾回收,而是 Java SE 6.0,这已不再需要

案例

 

解决方法

 

 

 

36.  SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH

 

类型

必改项

描述

A  value stored in the previous switch case is overwritten here due to a switch  fall through. It is likely that you forgot to put a break or return at the  end of the previous case.

 

swtich 中先前的 case 值因为 swtich 执行失败而被覆写,这就像是忘记使用 break 推出或者没有使用 return 语句放回先前的值一样。

案例

 

解决方法

 

 

 

37.  INT_BAD_COMPARISON_WITH_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 byteb to an unsigned value in the range 0..255, use0xff & b

 

比较有符合数,要先把有符号数转换为无符合数再进行比较

案例

 

解决方法

 

 

 

38.  NP_DEREFERENCE_OF_READLINE_VALUE

 

类型

必改项

描述

The  result of invoking readLine() is dereferenced without checking to see if the  result is null. If there are no more lines of text to read, readLine() will  return null and dereferencing that will generate a null pointer exception.

 

readLine() 的结果值没有进行判空操作就去重新赋值,这样的操作可以会抛出空指针异常。

案例

 

解决方法

 

 

 

39.  SA_FIELD_DOUBLE_ASSIGNMENT

 

类型

必改项

描述

This method contains a double assignment of  a field; e.g.

  int  x,y;

   public void foo() {

    x  = x = 17;

  }

Assigning to a field twice is useless, and  may indicate a logic error or typo.

 

方法中的字段包含了双重任务,例如:

 int x;

 public void foo() {

  x = x = 17;

 }

这种为变量赋值是无用的,并可能表明一个逻辑错误或拼写错误。

案例

 

解决方法

 

 

 

40.  DMI_INVOKING_TOSTRING_ON_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()方法,产生的结果形如 [@16f0472 并不能显示数组的真实内容。考虑使用 Arrays.toString 方法来转换成可读的字符串,提供该数组的内容数组

案例

 

解决方法

 

 

 

41.  EC_UNRELATED_TYPES

 

类型

必改项

描述

This  method calls equals(Object) on two references of different class types with  no common subclasses. Therefore, the objects being compared are unlikely to  be members of the same class at runtime (unless some application classes were  not analyzed, or dynamic class loading can occur at runtime). According to  the contract of equals(), objects of different classes should always compare  as unequal; therefore, according to the contract defined by  java.lang.Object.equals(Object), the result of this comparison will always be  false at runtime.

 

调用 equals 方法比较不同类型的类

案例

 

解决方法

 

 

 

42.  BC_IMPOSSIBLE_CAST

 

类型

必改项

描述

This  cast will always throw a ClassCastException. FindBugs tracks type information  from instanceof checks, and also uses more precise information about the  types of values returned from methods and loaded from fields. Thus, it may  have more precise information that just the declared type of a variable, and  can use this to determine that a cast will always throw an exception at  runtime.

 

不可能的类转换,执行时会抛出 ClassCastException

案例

 

解决方法

 

 

 

43.  ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND

 

类型

必改项

描述

This  code converts an int value to a float precision floating point number and  then passing the result to the Math.round() function, which returns the  int/long closest to the argument. This operation should always be a no-op,  since the converting an integer to a float should give a number with no  fractional part. It is likely that the operation that generated the value to  be passed to Math.round was intended to be performed using floating point  arithmetic.

 

int 类型的值转换为 float 类型之后调用了 Math.round 方法

案例

 

解决方法

 

 

 

44.  RV_RETURN_VALUE_IGNORED

 

类型

必改项

描述

The return value of this method should be  checked. One common cause of this warning is to invoke a method on an  immutable object, thinking that it updates the object. For example, in the  following code fragment,

String dateString = getHeaderField(name);

dateString.trim();

the programmer seems to be thinking that  the trim() method will update the String referenced by dateString. But since  Strings are immutable, the trim() function returns a new String value, which  is being ignored here. The code should be corrected to:

String dateString = getHeaderField(name);

dateString = dateString.trim();

 

该方法的返回值应该进行检查。这种警告通常出现在调用一个不可变对象的方法,认为它更新了对象的值。例如:String dateString = getHeaderField(name);

dateString.trim();

程序员似乎以为 trim()方法将更新 dateString 引用的字符串。但由于字符串是不可改变的,trim()函数返回一个新字符串值,在这里它是被忽略了。该代码应更正:

String dateString  = getHeaderField(name);

dateString =  dateString.trim();

 

案例

 

解决方法

 

 

 

45.  SF_SWITCH_FALLTHROUGH

 

类型

必改项

描述

This  method contains a switch statement where one case branch will fall through to  the next case. Usually you need to end this case with a break or return.

 

Switch 语句中一个分支执行后又执行了下一个分支。通常 case 后面要跟 break 或者 return 语句来跳出。

案例

int main(int argc, char* argv[])
  {
   printf("Hello World!/n");

 int num_of_operands = 2;


   //fall through 的设计可以把代码设计得很简约,
   // 以下的这个操作数处理是一个很好的例子,它可以很简约的去处理每一个操作数
   // 当然不得不说 switchfall through 设计为默认操作是引起许多 bug 的原因

 //session 1:
   switch(num_of_operands){
   case 2://process_operand(operator->operand_2);
   case 1://process_operand(operator->operand_1);
   default:;
   }

 //session 2: 即使是 default 没有 break,一样会出现 fall  through 现象
   num_of_operands = 2;
   switch(num_of_operands){
   case 1:
    printf("case 1 fall through/n");
   default:
    printf("default fall through/n");
    //num_of_operands = 10;
   case 3:
    printf("case 2 fall through/n");
   
   }

 //conclusion : 在使用 switch 时需要注意,如果是一般应用,请别忘了加上 break

 return 0;
  }

解决方法

在使用 switch 时需要注意,如果是一般应用,请别忘了加上 break

 

46.  DE_MIGHT_IGNORE

 

类型

必改项

描述

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.

 

方法可能忽略异常

案例

try{}catch(Exception  ex){}

 

解决方法

方法有可能抛异常或者忽略异常,需要对异常进行处理 , 即需要在 catch 体中对异常进行处理

 

47.  VA_FORMAT_STRING_EXTRA_ARGUMENTS_PASSED

 

类型

比改项

描述

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.

 

使用 String format 方法时有非法的参数也经过了格式化操作。

案例

这个错误很简单,是使用 String.format 的时候出了问题,format 里面的参数没有被全部用上。
看下面一段代码:
  public void test(){
      String str1 = "123";
      String str2 = "456";
      String str3 = String.format("{0} {1}" , str1 ,str2);
      System.out.println(str3);
  }
输出的结果是:{0}  {1}
 

解决方法

这个 Bug 描述就是这种问题,str1 str2 根本没有被用上!{0}{1} 这种 Format 格式是.NET 上面的用法,java 里面应该是 %s %s
这个是一个代码逻辑问题,可能是你写代码时不小心导致的,它在这段代码里不会导致异常,但往往会很可能导致其他地方异常,那时候你可能会百思不得其解。

 

 

48.  RE_POSSIBLE_UNINTENDED_PATTERN

 

类型

必改项

描述

A  String function is being invoked and "." 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, and s.split(".")always returns a zero length  array of String.

 

 

案例

if(version  != null && (!version.equalsIgnoreCase("")) &&  version.split(".").length < 4){

        this.m_txfSoftVersion.setVersion(version);

}

 

String split 方法传递的参数是正则表达式,正则表达式本身用到的字符需要转义,如:句点符号 ".",美元符号 "$",乘方符号 "^",大括号 "{}",方括号 "[]",圆括号 "()",竖线 "|",星号 "*",加号 "+",问号 "?" 等等,这些需要在前面加上 "\\" 转义符。

解决方法

在前面加上 "\\" 转义符

 

49.  SE_BAD_FIELD_INNER_CLASS

 

类型

必改项

描述

This Serializable class is an inner class  of a non-serializable class. Thus, attempts to serialize it will also attempt  to associate instance of the outer class with which it is associated, leading  to a runtime error.

If possible, making the inner class a  static inner class should solve the problem. Making the outer class  serializable might also work, but that would mean serializing an instance of  the inner class would always also serialize the instance of the outer class,  which it often not what you really want.

 

 

案例

 

解决方法

 

 

 

50.  RV_01_TO_INT

 

类型

必改项

描述

A  random value from 0 to 1 is being coerced to the integer value 0. You  probably want to multiple the random value by something else before coercing  it to an integer, or use theRandom.nextInt(n) method.

 

0 1 随机值被强制为整数值 0。在强制得到一个整数之前,你可能想得到多个随机值。或使用 Random.nextIntn)的方法。

案例

 

解决方法

 

 

 

51.  UW_UNCOND_WAIT

 

类型

必改项

描述

This  method contains a call tojava.lang.Object.wait() which is not  guarded by conditional control flow.  The code should verify that  condition it intends to wait for is not already satisfied before calling  wait; any previous notifications will be ignored.

 

方法中包含调用 java.lang.Object.wait(),而却没有放到条件流程控制中。该代码应确认条件尚未满足之前等待 ; 先前任何通知将被忽略。

案例

public class Test

{

      void clueless() throws Exception

      {

             synchronized(this)

             {

                    this.wait(); // VIOLATION

             }

      }

}

该检测模式寻找在进入同步块时无条件地 wait(),与 wait 相关的条件判断在无锁(不在同步块内)情况下进行的,有可能导致其它线程的 notification 被忽略。

解决方法

多线程错误 - 无条件等待

wait() 放到条件控制流中:If we are not enabled, then waitif (!enabled) { /* 条件判断不在同步块内 */

try {

synchronized (lock) {      /*if (!enabled) 应该在这里 */

lock.wait();

...

 

52.  UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS

 

类型

必改项

描述

This  anonymous class defined a method that is not directly invoked and does not  override a method in a superclass. Since methods in other classes cannot  directly invoke methods declared in an anonymous class, it seems that this  method is uncallable. The method might simply be dead code, but it is also  possible that the method is intended to override a method declared in a  superclass, and due to an typo or other error the method does not, in fact,  override the method it is intended to.

 

在匿名类中定义了一个既没有覆写超类中方法也不能直接调用的方法。因为在其他类的方法不能直接引用匿名类声明的方法,似乎这种方法不能被调用,这种方法可能只是没有任何作用的代码,但也可能覆写超类中声明。

案例

For example, in the following code, it is  impossible to invoke the initalValue method (because the name is misspelled  and as a result is doesn''t override a method in ThreadLocal).

private static ThreadLocal serialNum = new  ThreadLocal() {

         protected synchronized Object initalValue() {

             return new Integer(nextSerialNum++);

         }

      };

解决方法

错误用法 - 匿名内部类中定义的不可调用的方法

Added check for  uncallable method of an anonymous inner class.

 

53.  EQ_SELF_USE_OBJECT

 

类型

必改项

描述

This  class defines a covariant version of theequals() method, but  inherits the normalequals(Object) method defined in the basejava.lang.Object  class.  The class should probably define aboolean equals(Object) method.

 

类中定义了一组 equals 方法,但是都是继承的 java.lang.Object class 中的 equals(Object) 方法

案例

public class Point {

   private static double version = 1.0;

   private transient double distance;

   private int x, y;

  /* public  boolean equals(Object other) {

     if (other == this) return true;

     if (other == null) return false;

     if (getClass() != other.getClass()) return false;

     Point point = (Point)other;

     return (x == point.x && y == point.y);

  }  */

}

Point p1,p2;

if(p1.equals(p2)) return ture;

 

NoteRegardless  of which class contains the equals() method, the signature must always  declare an Object argument type. Since Java''s libraries look for one with an  Object argument, if the signature is not correct, then the java.lang.Object  method will be called instead, leading to incorrect behavior.

此处我们想比较的仅是 x y,而由于代码中未重写 equals() 方法,调用了 Object.equals(Object) 方法,对 distance version 也进行了比较。

解决方法

错误用法 - 协变 equals() 方法定义,继承了 Object.equals(Object)

类中增加 public boolean equals(Object) 方法的定义(见上例注释部分)。

 

54.  REC_CATCH_EXCEPTION

 

类型

必改项

描述

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.
 

try/catch 块中捕获异常,但是异常没有在 try 语句中抛出而 RuntimeException 又没有明确的被捕获

案例

public void addInstance(String className) {

     try {

        Class clazz = Class.forName(className);

        objectSet.add(clazz.newInstance());

    }

    catch (IllegalAccessException e) {

        logger.log("Exception in addInstance", e);

    }

     catch (InstantiationException e) {

        logger.log("Exception in addInstance", e);

    }

     catch (ClassNotFoundException e) {

        logger.log("Exception in addInstance", e);

    }

}

下面将上述代码中三个捕获块合并成捕获 Exception 的单独捕获块,因为每个捕获块的捕获恢复操作是相同的,这样便造成了未经检查的异常将被记录。

public void addInstance(String className) {

     try {

        Class clazz = Class.forName(className);

        objectSet.add(clazz.newInstance());

}

/* catch (RuntimeException e) {

       throw e;

} */

     catch (Exception e) {

        logger.log("Exception in newInstance", e);

    }

}

 

解决方法

错误用法 - 捕获了没有抛出的异常

因为 RuntimeException 扩展了 Exception,代码中增加捕获 RuntimeException,并在捕获 Exception 之前重新将其抛出。

 

55.  RU_INVOKE_RUN

 

类型

必改项

描述

This  method explicitly invokesrun() on an object.  In general,  classes implement theRunnable interface because they are going to have theirrun()  method invoked in a new thread, in which caseThread.start() is the  right method to call.

 

这种方法显式调用一个对象的 run()。一般来说,类是实现 Runnable 接口的,因为在一个新的线程他们将有自己的 run()方法,在这种情况下 Thread.start()方法调用是正确的。

案例

     public static void main(final String[] args) {

        System.out.println("Main thread: " +  Thread.currentThread().getId());

        final FooThread thread = new FooThread();

        thread.run();

        //thread.start();

    }

     public static class FooThread extends Thread

    {

        @Override

        public void run() {

            System.out.println("I''m executing from thread " +  Thread.currentThread().getId());

            super.run();

        }

    }

解决方法

多线程错误 - 在线程中调用了 run()

run() 方法只是类的一个普通方法而已,如果直接调用 run 方法,程序中依然只有主线程这一个线程。启动一个新的线程,我们不是直接调用 Thread 的子类对象的 run 方法,而是调用 Thread 子类对象的 start(从 Thread 类中继承的)方法,Thread 类对象的 start 方法将产生一个新的线程,并在该线程上运行该 Thread 类对象中的 run 方法,根据面向对象的多态性,在该线程上实际运行的是 Thread 子类(也就是我们编写的那个类)对象中的 run 方法。

 

56.  NP_SYNC_AND_NULL_CHECK_FIELD

 

类型

必改项

描述

Since  the field is synchronized on, it seems not likely to be null. If it is null  and then synchronized on a NullPointerException will be thrown and the check  would be pointless. Better to synchronize on another field.

 

如果代码块是同步的,那么久不可能为空。如果是空,同步时就会抛出 NullPointerException 异常。最好是在另一个代码块中进行同步。

案例

 

解决方法

 

 

 

57.  DLS_DEAD_STORE_OF_CLASS_LITERAL

 

类型

必改项

描述

This instruction assigns a class literal to  a variable and then never uses it.The behavior of this differs in Java 1.4  and in Java 5. In Java 1.4 and earlier, a reference to Foo.class would force the  static initializer for Foo to be executed, if it has not been executed  already. In Java 5 and later, it does not.

See Sun''sarticle on Java SE compatibility for more details and examples,  and suggestions on how to force class initialization in Java 5.

 

以类的字面名称方式为一个字段赋值后再也没有去使用它,在 1.4jdk 中它会自动调用静态的初始化方法,而在 jdk1.5 中却不会去执行。

案例

 

解决方法

 

 

 

58.  INT_BAD_REM_BY_1

 

类型

必改项

描述

Any  expression (exp % 1) is guaranteed to always return zero. Did you mean (exp  & 1) or (exp % 2) instead?

 

案例

 

解决方法

 

 

 

59.  DLS_DEAD_LOCAL_STORE_SHADOWS_FIELD

 

类型

必改项

描述

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. There is a field with the same name as the  local variable. Did you mean to assign to that variable instead?

 

案例

 

解决方法

 

 

 

60.  ST_WRITE_TO_STATIC_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.

 

案例

 

 

解决方法

 

 

 

61.  SWL_SLEEP_WITH_LOCK_HELD

 

类型

选改项

描述

This  method calls Thread.sleep() with a lock held. This may result in very poor  performance and scalability, or a deadlock, since other threads may be waiting  to acquire the lock. It is a much better idea to call wait() on the lock,  which releases the lock and allows other threads to run.

 

当持有对象时调用 Thread.sleep()。这可能会导致很差的性能和可扩展性,或陷入死锁,因为其他线程可能正在等待获得锁。调用 wait()是一个更好的主意,释放对象的持有以允许其他线程运行。

案例

 

 

解决方法

 

 

 

62.  LI_LAZY_INIT_STATIC

 

类型

选改项

描述

This  method contains an unsynchronized lazy initialization of a non-volatile  static field. Because the compiler or processor may reorder instructions,  threads are not guaranteed to see a completely initialized object, if the  method can be called by multiple threads. You can make the field  volatile to correct the problem. For more information, see theJava Memory Model web  site.

 

静态域不正确的延迟初始化。这种方法包含了一个不同步延迟初始化的非 volatile 静态字段。因为编译器或处理器可能会重新排列指令,如果该方法可以被多个线程调用,线程不能保证看到一个完全初始化的对象。可以让字段可变来解决此问题

案例

 

 

解决方法

 

 

 

63.  NM_SAME_SIMPLE_NAME_AS_SUPERCLASS

 

类型

选改项

描述

This  class has a simple name that is identical to that of its superclass, except  that its superclass is in a different package (e.g.,alpha.Foo  extendsbeta.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 accidently define methods that do not override  methods in their superclasses.

 

继承同一父类的子类不能使用相同的名称,即使它们位于不同的包中

案例

 

 

解决方法

 

 

 

64.  LI_LAZY_INIT_UPDATE_STATIC

 

类型

选改项

描述

This method  contains an unsynchronized lazy initialization of a static field. After the  field is set, the object stored into that location is further updated or  accessed. The setting of the field is visible to other threads as soon as it  is set. If the futher accesses in the method that set the field serve to  initialize the object, then you have avery serious multithreading  bug, unless something else prevents any other thread from accessing the  stored object until it is fully initialized.

Even if you  feel confident that the method is never called by multiple threads, it might  be better to not set the static field until the value you are setting it to  is fully populated/initialized.

这种方法包含一个不同步延迟初始化的静态字段。之后为字段赋值,对象存储到该位置后进一步更新或访问。字段后尽快让其他线程能够访问。如果该方法的进一步访问该字段为初始化对象提供服务,然后你有一个非常严重的多线程 bug,除非别的东西阻止任何其他线程访问存储的对象,直到它完全初始化。

即使你有信心,该方法是永远不会被多个线程调用时,在它的值还没有被充分初始化或移动,不把它设定为 static 字段时它可能会更好。

案例

 

解决方法

 

 

 

65.  GC_UNRELATED_TYPES

 

类型

选改项

描述

This call to a generic collection method  contains an argument with an incompatible class from that of the collection''s  parameter (i.e., the type of the argument is neither a supertype nor a  subtype of the corresponding generic type argument). Therefore, it is  unlikely that the collection contains any objects that are equal to the  method argument used here. Most likely, the wrong value is being passed to  the method.

In general, instances of two unrelated  classes are not equal. For example, if the Foo and Bar classes are not  related by subtyping, then an instance of Foo should not be equal to an  instance of Bar. Among other issues, doing so will likely result in an equals  method that is not symmetrical. For example, if you define the Foo class so  that a Foo can be equal to a String, your equals method isn''t symmetrical  since a String can only be equal to a String.

In rare cases, people do define  nonsymmetrical equals methods and still manage to make their code work.  Although none of the APIs document or guarantee it, it is typically the case  that if you check if a Collection<String> contains a Foo, the equals  method of argument (e.g., the equals method of the Foo class) used to perform  the equality checks.

 

 

案例

Foo<A, B>  foo;
  foo.remove(a, Collections<B>.emptySet()); //This generated a false  positive because it thinks that the second parameter should be of type B, not  Set<B>
 
  class Foo<X, Y> extends Bar<X, Set<Y>>{
  ...
  }
 
  class Bar<T, S> extends ConcurrentHashMap<T, S> {
  @Override
  public boolean remove(Object key, Object value) {
  ...
  }
  }

解决方法

 

 

 

66.  SC_START_IN_CTOR

 

类型

选改项

描述

The  constructor starts a thread. This is likely to be wrong if the class is ever extended/subclassed,  since the thread will be started before the subclass constructor is started

 

在构造函数中启动一个线程。如果类曾经被子类扩展过,那么这很可能是错的,因为线程将在子类构造之前开始启动。

案例

 

解决方法

 

 

 

67.  EQ_ALWAYS_FALSE

 

类型

选该项

描述

This class defines an equals method that  always returns false. This means that an object is not equal to itself, and  it is impossible to create useful Maps or Sets of this class. More  fundamentally, it means that equals is not reflexive, one of the requirements  of the equals method.

The likely intended semantics are object  identity: that an object is equal to itself. This is the behavior inherited  from class Object. If you need to override an equals inherited from a  different superclass, you can use use:

public boolean equals(Object o) { return  this == o; }

 

使用 equals 方法返回值总是 false

案例

 

解决方法

 

 

 

68.  RC_REF_COMPARISON

 

类型

选改项

描述

This  method compares two reference values using the == or != operator, where the  correct way to compare instances of this type is generally with the equals()  method. It is possible to create distinct instances that are equal but do not  compare as == since they are different objects. Examples of classes which  should generally not be compared by reference are java.lang.Integer,  java.lang.Float, etc.

 

比较两个对象值是否相等时应该采用 equals 方法,而不是 == 方法

案例

 

解决方法

 

 

 

69.  IJU_ASSERT_METHOD_INVOKED_FROM_RUN_METHOD

 

类型

选改项

描述

A  JUnit assertion is performed in a run method. Failed JUnit assertions just  result in exceptions being thrown. Thus, if this exception occurs in a thread  other than the thread that invokes the test method, the exception will  terminate the thread but not result in the test failing.

 

JUnit 中的断言在 run 方法中不会被告知

案例

 

解决方法

 

 

 

70.  STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE

 

类型

选改项

描述

As the JavaDoc states, DateFormats are  inherently unsafe for multithreaded use. The detector has found a call to an  instance of DateFormat that has been obtained via a static field. This looks  suspicous.

For more information on this seeSun Bug #6231579 andSun Bug #6178997.

 

在官方的 JavaDocDateFormats 多线程使用本事就是不安全的。探测器发现调用一个 DateFormat 的实例将会获得一个静态对象。

myString =  DateFormat.getDateInstance().format(myDate);

 

案例

 

解决方法

 

 

 

71.  STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE

 

类型

选改项

描述

As the JavaDoc states, DateFormats are  inherently unsafe for multithreaded use. Sharing a single instance across  thread boundaries without proper synchronization will result in erratic  behavior of the application.

You may also experience serialization  problems.

Using an instance field is recommended.

For more information on this seeSun Bug #6231579 andSun Bug #6178997.

 

DateFormat 在多线程中本身就是不安全的,如果在线程范围中共享一个 DateFormat 的实例而不使用一个同步的方法在应用中就会出现一些奇怪的行为。

案例

 

解决方法

 

 

 

72.  AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTR

ACTION

 

类型

选改项

描述

This  code contains a sequence of calls to a concurrent abstraction (such as a  concurrent hash map). These calls will not be executed atomically.

 

 

案例

 

解决方法

 

 

 

73.  BC_UNCONFIRMED_CAST

 

类型

选改项

描述

This  cast is unchecked, and not all instances of the type casted from can be cast  to the type it is being cast to. Check that your program logic ensures that  this cast will not fail.

 

强制类型转换操作没有经过验证,而且不是所有的此种类型装换过的类都可以再强制类型转换为原类型。在代码中需要进行逻辑判断以保证可以进行这样的操作。

案例

 

解决方法

 

 

 

74.  RV_ABSOLUTE_VALUE_OF_RANDOM_INT

 

类型

选改项

描述

This  code generates a random signed integer and then computes the absolute value  of that random integer. If the number returned by the random number generator  isInteger.MIN_VALUE, then the result will be negative as well (sinceMath.abs(Integer.MIN_VALUE) ==  Integer.MIN_VALUE). (Same problem arised for  long values as well).

 

此代码生成一个随机的符号整数,然后计算该随机整数的绝对值。如果随机数生成数绝对值为 Integer.MIN_VALUE 的,那么结果将是负数(因为 Math.absInteger.MIN_VALUE 的)== Integer.MIN_VALUE 的)。

案例

public intgetAbsRandom() {

       Random random = new Random();

       int raw = random.nextInt();

       returnMath.abs(raw);

       }

解决方法

对产生的随机数做判断,是否为 Integer.MIN_VALUE 特殊情况

 

75.  NN_NAKED_NOTIFY

 

类型

选改项

描述

A call to notify() or notifyAll() was made  without any (apparent) accompanying modification to mutable object  state.  In general, calling a notify method on a monitor is done because  some condition another thread is waiting for has become true.  However,  for the condition to be meaningful, it must involve a heap object that is  visible to both threads.

This bug does not necessarily indicate an  error, since the change to mutable object state may have taken place in a  method which then called the method containing the notification.

 

赤裸的通知

案例

protectedvoid notifyExchange(MessageExchangeImpl me, Object lock, String from) {
          if (LOG.isDebugEnabled()) {
             LOG.debug("Notifying exchange " + me.getExchangeId() +  "(" + Integer.toHexString(me.hashCode()) + ") in " +this + " from "+ from);
           }
        &nb  sp; synchronized (lock) {
              lock.notify();
           }
     }

解决方法

 

 

 

76.  BC_IMPOSSIBLE_INSTANCEOF

 

类型

选改项

描述

This  instanceof test will always return false. Although this is safe, make sure it  isn''t an indication of some misunderstanding or some other logic error.

 

采用 instaneof 方法进行比较时总是返回 false。前提是保证它不是由于某些逻辑错误造成的。

案例

publicclass Person {

    publicclass Sunextends Person

    {

          …….

    }

    public boolean isPerson(){

       Person obj = new Person();

        if(obj instanceof  Sun){

           returntrue;

       }

       returnfalse;

    }

解决方法

防止这类错误出现

 

77.  DMI_RANDOM_USED_ONLY_ONCE

 

类型

选改项

描述

This code creates a java.util.Random  object, uses it to generate one random number, and then discards the Random  object. This produces mediocre quality random numbers and is inefficient. If  possible, rewrite the code so that the Random object is created once and  saved, and each time a new random number is required invoke a method on the  existing Random object to obtain it.

If it is important that the generated  Random numbers not be guessable, youmust not create a new Random for  each random number; the values are too easily guessable. You should strongly  consider using a java.security.SecureRandom instead (and avoid allocating a  new SecureRandom for each random number needed).

 

随机创建对象只使用过一次就抛弃

案例

 

publicint getRandom(int seed){

       return new  Random(seed).nextInt();

    }

 

解决方法

findbugs 建议使用 SecureRandom

publicint getRandom(byte[] seed){

       returnnew SecureRandom(seed).nextInt(); 

    }

 

 

78.  NP_GUARANTEED_DEREF_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).

 

 

案例

 

解决方法

 

 

 

79.  WA_NOT_IN_LOOP

 

类型

选改项

描述

This method contains a call to java.lang.Object.wait()  which is not in a loop.  If the monitor is used for multiple conditions,  the condition the caller intended to wait for might not be the one that  actually occurred.

 

这种方法包含调用 java.lang.Object.wait(),而这并不是一个循环。如果监视器用于多个条件,打算调用 wait() 方法的条件可能不是实际发生的。

 

案例

protectedvoid waitForExchange(MessageExchangeImpl me, Object  lock,long timeout, String from)throws InterruptedException {

        // If the channel is closed while here, we must abort

       if (LOG.isDebugEnabled()) {

           LOG.debug("Waiting for exchange " + me.getExchangeId() +" (" +  Integer.toHexString(me.hashCode()) +") to be answered in "

                            + this + " from " + from);

        }

        Thread th = Thread.currentThread();

        try {

            waiters.put(th,  Boolean.TRUE);

            lock.wait(timeout);

      } finally {

            waiters.remove(th);

      }

        if (LOG.isDebugEnabled()) {

           LOG.debug("Notified: " + me.getExchangeId() +"(" + Integer.toHexString(me.hashCode()) +") in " + this +" from " + from);

        }

    }

解决方法

 

 

 

 

 

 

 

 

 

整理的行业规则:

80.  OBL_UNSATISFIED_OBLIGATION

 

类型

必改项

描述

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 findbugs@cs.umd.edu
  • 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.

这种方法可能无法清除(关闭,处置)一个流,数据库对象,或其他资源需要一个明确的清理行动。

一般来说,如果一个方法打开一个流或其他资源,该方法应该使用 try / finally 块来确保在方法返回之前流或资源已经被清除了。这种错误模式基本上和 OS_OPEN_STREAM ODR_OPEN_DATABASE_RESOURCE 错误模式相同,但是是在不同在静态分析技术。我们正为这个错误模式的效用收集反馈意见。

案例

 

解决方法

 

 

 

81.  IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION

 

类型

必改项

描述

During  the initialization of a class, the class makes an active use of a subclass.  That subclass will not yet be initialized at the time of this use. For  example, in the following code,foo  will be null.

public class CircularClassInitialization {

    static class InnerClassSingleton extends CircularClassInitialization {

        static InnerClassSingleton singleton = new InnerClassSingleton();

    }

 

    static CircularClassInitialization foo = InnerClassSingleton.singleton;

}

 

子类在父类未初始化之前使用父类对象实例

案例

 

解决方法

 

 

 

82.  IMSE_DONT_CATCH_IMSE

 

类型

必改项

描述

IllegalMonitorStateException is generally  only thrown in case of a design flaw in your code (calling wait or notify on  an object you do not hold a lock on).

 

捕捉违法的监控状态异常,例如当没有获取到对象锁时使用其 wait notify 方法

案例

 

解决方法

 

 

 

83.  IL_INFINITE_LOOP

 

类型

必改项

描述

This loop doesn''t seem to have a way to  terminate (other than by perhaps throwing an exception).

 

方法的自调用引起的死循环

案例

 

解决方法

 

 

 

84.  NP_CLOSING_NULL

 

类型

必改项

描述

close() is being invoked on a value that is  always null. If this statement is executed, a null pointer exception will  occur. But the big risk here you never close something that should be closed.

 

一个为空的对象调用 close 方法

案例

 

解决方法

 

 

 

85.  NP_NONNULL_PARAM_VIOLATION

 

类型

必改项

描述

This  method passes a null value as the parameter of a method which must be  nonnull. Either this parameter has been explicitly marked as @Nonnull, or  analysis has determined that this parameter is always dereferenced.

 

方法中为 null 的参数没有被重新赋值

案例

 

解决方法

 

 

 

86.  NP_NONNULL_RETURN_VIOLATION

 

类型

必改项

描述

This  method may return a null value, but the method (or a superclass method which  it overrides) is declared to return @NonNull.

 

方法声明了返回值不能为空,但是方法中有可能返回 null

案例

void test(){

             String ss = null;

             sya(ss);

      }     

      public void sya(String ad){

             ad.getBytes();

      }

解决方法

 

 

 

87.  NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS

 

类型

必改项

描述

A  possibly-null value is passed at a call site where all known target methods  require the parameter to be nonnull. Either the parameter is annotated as a  parameter that should always be nonnull, or analysis has shown that it will  always be dereferenced.

 

方法参数中声明为 nonnull 类型的参数为 null

案例

 

解决方法

 

 

 

88.  NM_BAD_EQUAL

 

类型

必改项

描述

This  class defines a methodequal(Object).  This method does not override theequals(Object) method injava.lang.Object, which is probably what was intended.

 

类中定义了一个 equal 方法但是却不是覆写的 Object 对象的 equals 方法

案例

 

解决方法

 

 

 

 

89.  SA_LOCAL_SELF_COMPUTATION

 

类型

必改项

描述

This  method performs a nonsensical computation of a local variable with another  reference to the same variable (e.g., x&x or x-x). Because of the nature  of the computation, this operation doesn''t seem to make sense, and may  indicate a typo or a logic error. Double check the computation.

 

此方法对同一变量执行了荒谬的计算(如 x&x x-x)操作。由于计算的性质,这一行动似乎没有意义,并可能表明错误或逻辑错误。

案例

 

解决方法

 

 

 

90.  UR_UNINIT_READ_CALLED_FROM_SUPER_CONSTRUCTOR

 

类型

必改项

描述

This method is invoked in the constructor  of of the superclass. At this point, the fields of the class have not yet  initialized.

To make this more concrete, consider the  following classes:

When a B is constructed, the constructor  for the A class is invokedbefore the constructor for B sets value.  Thus, when the constructor for A invokes getValue, an uninitialized value is  read for value

 

方法被超类的构造函数调用时,在当前类中的字段或属性还没有被初始化

 

案例

abstract class A {

  int  hashCode;

   abstract Object getValue();

  A()  {

     hashCode = getValue().hashCode();

    }

  }

class B extends A {

   Object value;

   B(Object v) {

     this.value = v;

    }

   Object getValue() {

     return value;

  }

  }

 

 

B 是创建时,A 的构造函数将在 B value 赋值之前触发,然而在 A 的初始化方法调用 getValue 方法时 value 这个变量还没有被初始化。

解决方法

 

 

 

91.  DMI_INVOKING_TOSTRING_ON_ANONYMOUS_ARRAY

 

类型

必改项

描述

The  code invokes toString on an (anonymous) array. Calling toString on an array  generates 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()方法,产生的结果形如 [@16f0472 并没有实际的意义。考虑使用 Arrays.toString 方法来转换成可读的字符串,提供该数组的内容数组。

案例

String[] a = { "a" };

System.out.println(a.toString());

 

解决方法

// 正确的使用为

System.out.println(Arrays.toString(a));

 

 

92.  UWF_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.

 

此字段是永远不会写入值。所有读取将返回默认值。检查错误(如果它被初始化?),如果它确实没有用就删除掉。

案例

 

解决方法

 

 

 

93.  DM_STRING_VOID_CTOR

 

类型

必改项

描述

Creating  a newjava.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 sameString object.  Therefore, you should just use the empty string  constant directly.

 

使用没有参数的构造方法去创建新的 String 对象是浪费内存空间的,因为这样创建会和空字符串 “” 混淆。Java 中保证完成相同的构造方法会产生描绘相同的 String 对象。所以你只要使用空字符串来创建就可以了。

案例

 

解决方法

 

 

 

94.  SBSC_USE_STRINGBUFFER_CONCATENATION

 

类型

必改项

描述

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:

 

在循环中构建一个 String 对象时从性能上讲使用 StringBuffer 来代替 String 对象

案例

// 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();

 

 

95.  BC_BAD_CAST_TO_CONCRETE_COLLECTION

 

类型

必改项

描述

This  code casts an abstract collection (such as a Collection, List, or Set) to a  specific concrete implementation (such as an ArrayList or HashSet). This  might not be correct, and it may make your code fragile, since it makes it  harder to switch to other concrete implementations at a future point. Unless  you have a particular reason to do so, just use the abstract collection  class.

 

代码把抽象的集合(如 ListSet,或 Collection)强制转换为具体落实类型(如一个 ArrayList HashSet)。这可能不正确,也可能使您的代码很脆弱,因为它使得难以在今后的切换指向其他具体实现。除非你有特别理由这样做,否则只需要使用抽象的集合类。

案例

 

解决方法

 

 

 

96.  DLS_DEAD_LOCAL_STORE

 

类型

必改项

描述

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. 

 

该指令为局部变量赋值,但在其后的没有对她做任何使用。通常,这表明一个错误,因为值从未使用过。

案例

 

解决方法

 

 

 

97.  NS_NON_SHORT_CIRCUIT

 

类型

必改项

描述

This code seems to be using  non-short-circuit logic (e.g., & or |) rather than short-circuit logic  (&& or ||). Non-short-circuit logic causes both sides of the  expression to be evaluated even when the result can be inferred from knowing  the left-hand side. This can be less efficient and can result in errors if  the left-hand side guards cases when evaluating the right-hand side can  generate an error.

See the Java Language Specification for details

 

代码中使用(& or |)代替(&& or ||)操作,会引起不安全的操作

案例

 

解决方法

 

 

 

98.  RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE

 

类型

必改项

描述

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

 

方法中对不为空的值进行为空的判断

案例

 

解决方法

 

 

 

99.  RI_REDUNDANT_INTERFACES

 

类型

必改项

描述

This  class declares that it implements an interface that is also implemented by a  superclass. This is redundant because once a superclass implements an  interface, all subclasses by default also implement this interface. It may  point out that the inheritance hierarchy has changed since this class was  created, and consideration should be given to the ownership of the  interface''s implementation.

 

子类和父类都实现了同一个接口,这种定义是多余的。

案例

 

解决方法

 

 

 

100.          SA_LOCAL_DOUBLE_ASSIGNMENT

 

类型

必改项

描述

This method contains a double assignment of  a local variable; e.g.

   public void foo() {

     int x,y;

    x  = x = 17;

  }

Assigning the same value to a variable  twice is useless, and may indicate a logic error or typo.

 

为一个局部变量两次赋值,这样是没有意义的

案例

 

解决方法

 

 

 

101.          SA_LOCAL_SELF_ASSIGNMENT

 

类型

必改项

描述

This method contains a self assignment of a  local variable; e.g.

   public void foo() {

     int x = 3;

    x  = x;

  }

Such assignments are useless, and may  indicate a logic error or typo

 

局部变量使用自身给自己赋值

案例

 

解决方法

 

 

 

102.          SF_SWITCH_NO_DEFAULT

 

类型

必改项

描述

This  method contains a switch statement where default case is missing. Usually you  need to provide a default case.

 

Switch 没有默认情况下执行的 case 语句

案例

 

解决方法

 

 

 

103.          UCF_USELESS_CONTROL_FLOW

 

类型

必改项

描述

This method contains a useless control flow  statement, where control flow continues onto the same place regardless of  whether or not the branch is taken. For example, this is caused by having an  empty statement block for an if statement:

 

     if (argv.length == 0) {

     // TODO: handle this case

    }

 

没有任何作用的条件语句

案例

 

解决方法

 

 

 

104.          UCF_USELESS_CONTROL_FLOW_NEXT_LINE

 

类型

必改项

描述

This method contains a useless control flow  statement in which control flow follows to the same or following line  regardless of whether or not the branch is taken. Often, this is caused by  inadvertently using an empty statement as the body of an if statement, e.g.:

   

 

无效的条件控制语句

案例

if (argv.length == 1);

        System.out.println("Hello, " + argv[0]);

无效的条件控制语句,注意 if (argv.length == 1); “;” 结尾,下面的语句无论是否满足都会运行。

解决方法

 

 

 

105.          NP_BOOLEAN_RETURN_NULL

 

类型

必改项

描述

A  method that returns either Boolean.TRUE, Boolean.FALSE or null is an accident  waiting to happen. This method can be invoked as though it returned a value  of type boolean, and the compiler will insert automatic unboxing of the  Boolean value. If a null value is returned, this will result in a  NullPointerException.

 

返回值为 boolean 类型的方法直接返回 null,这样会导致空指针异常

案例

 

解决方法

 

 

 

106.          SI_INSTANCE_BEFORE_FINALS_ASSIGNED

 

类型

必改项

描述

The  class''s static initializer creates an instance of the class before all of the  static final fields are assigned.

 

在所有的 static final 字段赋值之前去使用静态初始化的方法创建一个类的实例。

案例

 

解决方法

 

 

 

107.          VA_FORMAT_STRING_BAD_ARGUMENT

 

类型

必改项

描述

The format string placeholder is  incompatible with the corresponding argument. For example,  System.out.println("%d\n", "hello");

The %d placeholder requires a numeric  argument, but a string value is passed instead. A runtime exception will  occur when this statement is executed.

 

错误使用参数类型来格式化字符串

 

案例

 

解决方法

 

 

 

108.          MF_METHOD_MASKS_FIELD

 

类型

必改项

描述

This  method defines a local variable with the same name as a field in this class  or a superclass. This may cause the method to read an uninitialized value  from the field, leave the field uninitialized, or both.

 

在方法中定义的局部变量和类变量或者父类变量同名,从而引起字段混淆。

案例

 

解决方法

 

 

 

109.          NP_ARGUMENT_MIGHT_BE_NULL

 

类型

必改项

描述

A  parameter to this method has been identified as a value that should always be  checked to see whether or not it is null, but it is being dereferenced  without a preceding null check.

 

方法没有判断参数是否为空

案例

 

解决方法

 

 

 

110.          MWN_MISMATCHED_NOTIFY

 

类型

必改项

描述

This  method calls Object.notify() or Object.notifyAll() without obviously holding  a lock on the object.  Calling notify() or notifyAll() without a lock  held will result in anIllegalMonitorStateException being thrown.

 

此方法调用 Object.notify()或 Object.notifyAll()而没有获取到该对象的对象锁。调用 notify()或 notifyAll()而没有持有该对象的对象锁,将导致 IllegalMonitorStateException 异常。

案例

 

解决方法

 

 

 

111.          MWN_MISMATCHED_WAIT

 

类型

必改项

描述

This  method calls Object.wait() without obviously holding a lock on the  object.  Calling wait() without a lock held will result in anIllegalMonitorStateException being thrown.

 

此方法调用 Object.wait() 而没有获取到该对象的对象锁。调用 wait()而没有持有该对象的对象锁,将导致 IllegalMonitorStateException 异常。

案例

 

解决方法

 

 

 

112.          UL_UNRELEASED_LOCK

 

类型

必改项

描述

This method  acquires a JSR-166 (java.util.concurrent) lock, but does not release it on  all paths out of the method. In general, the correct idiom for using a  JSR-166 lock is:

   Lock l = ...;

   l.lock();

   try {

       // do something

   } finally {

       l.unlock();

   }

 

 

方法获得了当前的对象所,但是在方法中始终没有释放它

案例

Lock l = ...;

   l.lock();

   try {

       // do something

   } finally {

       l.unlock();

   }

解决方法

 

 

 

 

 

 

FindBugs 2.0.1 RC3 发布

FindBugs 2.0.1 RC3 发布

OSC 请你来轰趴啦!1028 苏州源创会,一起寻宝 AI 时代

FindBugs 2.0.1 发布了第三个 RC 版本,下载地址:findbugs-2.0.1-rc3.zip (8.3 MB)

FindBugs 是一个能静态分析源代码中可能会出现 Bug 的 Eclipse 插件工具。

我们今天的关于findbugs和数据库密码安全性问题数据库中的访问密钥和安全锁的分享就到这里,谢谢您的阅读,如果想了解更多关于2.findbugs 总结、Debian 11.2 发布,修复 Bug 及安全性问题、findbugs、FindBugs 2.0.1 RC3 发布的相关信息,可以在本站进行搜索。

本文标签: