findbugs 接口文档_FindBugs代码质量检查(持续更新)

本文详细介绍了FindBugs工具在代码质量检查中发现的24种不同类型的缺陷,包括不良习惯、正确性、糟糕的代码、性能、安全、多线程的正确等多个方面。通过具体的代码示例,展示了如CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE、DMI_RANDOM_USED_ONLY_ONCE、ODR_OPEN_DATABASE_RESOURCE等问题,并提供了相应的解决办法,旨在提升代码质量和安全性。
摘要由CSDN通过智能技术生成

一、前言

目前已验证缺陷检查规则24条。其中不良习惯(Bad practice)14条,正确性(Correctness)3条,

糟糕的代码(Dodgy code)3条,性能(Performance)1条,安全(Security)2条,多线程的正确(Multithreaded correctness)1条;

其中ODR_OPEN_DATABASE_RESOURCE_EXCEPTION_PATH、

OS_OPEN_STREAM_EXCEPTION_PATH、DE_MIGHT_IGNORE这三个检查点存在缺陷,代码进行变更修改后检查点无法检测到错误异常。其余可正常进行逻辑检查。

二、缺陷集合

1、CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE

1.1 缺陷说明

这个检测器会检查编写的可克隆类是否违反惯用语法。类定义了clone()方法,但是没有实现Cloneable接口。

如果不继承自Cloneable接口,当调用clone()时会抛出CloneNotSupportedException异常。

1.2 代码示例

public class CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE{

public Object clone() throws CloneNotSupportedException{

return super.clone();

}

}

1.3 解决方式

public class CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE_U implements Cloneable{

public Object clone() throws CloneNotSupportedException{

return super.clone();

}

}

2、DMI_RANDOM_USED_ONLY_ONCE

2.1 缺陷说明

代码中调用无意义方法的地方;由于java.util.Random是一个伪随机函数,如果传入的参数相同的话,

返回的随机数就是相同的。因此没必要每次都new一个新的random出来计算随机数,建议使用

java.security.SecureRandom,该类继承自Random,是一个强随机数生成器。

2.2 代码示例

public class DMI_RANDOM_USED_ONLY_ONCE{

public static int getRandom(int seed){

return new Random(seed).nextInt();

}

}

2.3 解决方式

public class DMI_RANDOM_USED_ONLY_ONCE_U{

public static int getRandom(int seed){

SecureRandom SR = new SecureRandom();

return SR.nextInt();

}

}

3、DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION

3.1 缺陷说明

建议不要使用 collection.removeAll(collection)方法来删除 collection中的所有元素,而使用

collection.clear()。removeAll是比较参数中的collection和要移除元素的collection中是否有交集,

然后将交集元素删除;clear()是直接将collenction中的元素删除,后者要比前者高效。

3.2 代码示例

public class DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION {

public void collClear(){

List list = new ArrayList<>();

list.add(ddd);

list.removeAll(list);

}

}

3.3 解决方式

public class DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION_U{

public void collClear(){

Collection coll = new ArrayList();

coll.clear();

}

}

4、ICAST_INTEGER_MULTIPLY_CAST_TO_LONG

4.1 缺陷说明

将整数乘法运算的结果转换为long型,结果可能会因为超出整形的范围而出错。

4.2 代码示例

public class ICAST_INTEGER_MULTIPLY_CAST_TO_LONG{

static final long MILLISECONDS_PER_DAY = 24L * 3600 * 1000;

long convertDaysToMilliseconds(int days){

return 1000 * 3600 * 24 * days;

}

}

4.3 解决方式

public class ICAST_INTEGER_MULTIPLY_CAST_TO_LONG_U{

static final long MILLISECONDS_PER_DAY = 24L * 3600 * 1000;

long convertDaysToMilliseconds(int days){

return 1000L * 3600 * 24 * days;

}

}

5、ODR_OPEN_DATABASE_RESOURCE

5.1 缺陷说明

这个检测器会找出退出方法时没有及时关闭的I/O流对象。方法未能成功关闭数据库资源。

5.2 代码示例

public void exec(){

try {

Class.forName(oracle.jdbc.driver.OracleDriver);

Connection conn = DriverManager.getConnection(Config.par.get(url),Config.par.get(userName),Config.par.get(passWord));

conn.clearWarnings();

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

5.3 解决方式

public void exec() throws SQLException{

Connection conn = null;

try {

Class.forName(oracle.jdbc.driver.OracleDriver);

conn = DriverManager.getConnection(Config.par.get(url), Config.par.get(userName),Config.par.get(passWord));

conn.clearWarnings();

conn.close();

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

6、OS_OPEN_STREAM

6.1 缺陷说明

这个检测器会找出退出方法时没有及时关闭的I/O流对象。方法未能成功关闭流。

6.2 代码示例

public static void exec(String path){

try {

File f = new File(path);

FileWriter fw = new FileWriter(f);

fw.write(xxxxx);

fw.flush();

} catch (Exception e) {

e.printStackTrace();

} finally {

}

}

6.3 解决方式

public static void exec(String path) throws IOException{

FileWriter fw = null;

try {

File f = new File(path);

fw = new FileWriter(f);

fw.write(xxxxx);

fw.flush();

} catch (Exception e) {

e.printStackTrace();

} finally {

if(fw!=null) fw.close();

}

}

7、RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN

7.1 缺陷说明

使用== 或者 !=操作符来比较两个Boolean类型的对象,可能会产生错误,建议使用equals方法。

(如下所示,缺陷实例方法返回值为false,解决实例返回值为true)

7.2 代码示例

public boolean exec() {

Boolean b1 = new Boolean(true);

Boolean b2 = new Boolean(true);

return b1==b2;

}

7.3 解决方式

public boolean exec() {

Boolean b1 = new Boolean(true);

Boolean b2 = new Boolean(true);

return b1.equals(b2);

}

8、RV_RETURN_VALUE_IGNORED

8.1 缺陷说明

这个检测器会找出代码中调用带有返回值的方法,但是可疑地忽略掉方法返回值的地方。

8.2 代码示例

public static String getHeaderField(String name) {

return “”;

}

public String exec() {

String dateString = getHeaderField();

dateString.trim();

return dateString;

}

8.3 解决方式

public static String getHeaderField(String name) {

return "";

}

public String exec() {

String dateString = getHeaderField();

dateString = dateString.trim();

return dateString;

}

9、ODR_OPEN_DATABASE_RESOURCE_EXCEPTION_PATH

9.1 缺陷说明

这个检测器会找出退出方法时没有及时关闭的I/O流对象。异常发生时,方法未能成功关闭数据库资源。

【未对数据库连接资源进行关闭操作,检查点无法检查到异常点】

9.2 代码示例

public void exec(){

try {

Class.forName(oracle.jdbc.driver.OracleDriver);

String url = jdbc:oracle:thin:@127.0.0.1:1521:ORCL;

Connection conn = DriverManager.getConnection(url, Config.par.get(userName),Config.par.get(passWord));

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

9.3 解决方式

public void exec() throws SQLException{

Connection conn = null;

try {

Class.forName(oracle.jdbc.driver.OracleDriver);

String url = jdbc:oracle:thin:@127.0.0.1:1521:ORCL;

conn = DriverManager.getConnection(url, Config.par.get(userName),Config.par.get(passWord));

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}finally{

if(conn!=null) conn.close();

}

}

10、OS_OPEN_STREAM_EXCEPTION_PATH

10.1 缺陷说明

这个检测器会找出退出方法时没有及时关闭的I/O流对象。异常发生时,方法未能成功关闭流。

【未对文件流进行关闭操作,检查点未能检测到异常】

10.2 代码示例

public void readFileByBytes(String path){

try {

File f = new File(path);

FileWriter fw = new FileWriter(f);

fw.write(xxxxx);

fw.flush();

} catch (IOException e) {

e.printStackTrace();

}

}

10.3 解决方式

public void readFileByBytes(String path) throws IOException{

FileWriter fw = null;

try {

File f = new File(path);

fw = new FileWriter(f);

fw.write(xxxxx);

fw.flush();

} catch (IOException e) {

e.printStackTrace();

}finally{

if(fw!=null)fw.close();

}

}

11、DMI_HARDCODED_ABSOLUTE_FILENAME

11.1 缺陷说明

代码含有指向一个绝对路径名的硬编码引用。

11.2 代码示例

public void exec(){

File file = new File(c:\\a.txt);

if(file.exists()){

}

}

11.3 解决方式

public void exec() {

String path = ABSOLUTE_FILENAME_U.class.getResource().getPath();

File file = new File(path+/home/testdir);

if(file.exists()){

}

}

12、DMI_CONSTANT_DB_PASSWORD

12.1 缺陷说明

数据库密码的硬编码常量,代码中创建DB的密码时采用了写死的密码。

12.2 代码示例

public void exec() throws SQLException {

Connection conn = null;

try {

Class.forName(oracle.jdbc.driver.OracleDriver);

String url = jdbc:oracle:thin:@127.0.0.1:1521:ORCL;

String UserName = "admin";

String Password = "123456";

conn = DriverManager.getConnection(url, UserName, Password);

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} finally {

if (conn != null)

conn.close();

}

}

12.3 解决方式

public void exec() throws SQLException {

Connection conn = null;

try {

Class.forName(oracle.jdbc.driver.OracleDriver);

String url = jdbc:oracle:thin:@127.0.0.1:1521:ORCL;

String UserName = "admin";

String Password = Config.par.get(passWord);

conn = DriverManager.getConnection(url, UserName, Password);

} catch (SQLException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} finally {

if (conn != null)

conn.close();

}

}

13、SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE

13.1 缺陷说明

这个检测器会通过数据流分析检查执行SQL语句的方法调用,

找出那些没有使用常量字符串作为实参的方法调用。

13.2 代码示例

public void exec() throws SQLException{

Connection conn = null;

ResultSet res = null;

Statement state = null;

String username = admin;

try {

conn = DriverManager.getConnection(Config.par.get(url),Config.par.get(userName),Config.par.get(passWord));

state = conn.createStatement();

res = state.executeQuery(select * from t_user t where t.username=' + username+');

} catch (SQLException e) {

e.printStackTrace();

}finally{

if(state!=null)

state.close();

if(res!=null)

res.close();

if(conn!=null)

conn.close();

}

}

13.3 解决方式

public void exec() throws SQLException{

Connection conn = null;

ResultSet res = null;

Statement state = null;

try {

conn = DriverManager.getConnection(Config.par.get(url),Config.par.get(userName),Config.par.get(passWord));

if(conn!=null){

String sql = select * from t_user t where t.username=?;

PreparedStatement pstmt = conn.prepareStatement(sql);

pstmt.setString(0, sss);

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

if(state!=null)

state.close();

if(res!=null)

res.close();

if(conn!=null)

conn.close();

}

}

14、SBSC_USE_STRINGBUFFER_CONCATENATION

14.1 缺陷说明

这个检测器会找出在循环中使用“+”运算符拼接字符串的地方。每次循环里的字符串+连接,

都会新产生一个string对象,效率较低,建议利用StringBuffer或者StringBuilder重用对象

14.2 代码示例

public String exec() {

String str = "abc";

for (int i = 0; i < 5; i++) {

str += String.valueOf(i);

}

return str;

}

14.3 解决方式

public String exec(){

StringBuffer str = new StringBuffer();

str.append("abc");

for (int i = 0; i < 5; i++) {

str.append(i);

}

return str.toString();

}

15、NP_SYNC_AND_NULL_CHECK_FIELD

15.1 缺陷说明

这个检测器会找出代码中进行同步操作,然后又检查是否为空值的字段。

如果代码块是同步的,那么就不可能为空。如果是空,同步时就会抛出NullPointerException异常。

15.2 代码示例

public static String getTableLastUpdateTime(String tableName) {

String time = null;

synchronized (Config.par) {

if (Config.par != null) { // 这句判断是多余的,可以去掉!

time = Config.par.get(passWord);

} else {

}

}

return time;

}

15.3 解决方式

public static String getTableLastUpdateTime(String tableName){

String time = null;

synchronized (Config.par.get(passWord)) {

time = Config.par.get(passWord);

}

return time;

}

16、UR_UNINIT_READ

16.1 缺陷说明

这个检测器会检查构造器中是否读取未初始化的字段。

16.2 代码示例

String a;

public UR_UNINIT_READ(){

String abc = a;

System.out.println(abc);

}

16.3 解决方式

String a ="";

public UR_UNINIT_READ_U(){

String abc = a;

System.out.println(abc);

}

17、DE_MIGHT_IGNORE

17.1 缺陷说明

方法可能忽略异常,应该将异常处理、打印或者抛出

17.2 代码示例

public void exec(){

try {

Integer in = Integer.valueOf(xxx);

if(in>100){

}

} catch (Exception e) {}

}

17.3 解决方式

public void exec() {

try {

Integer temp = Integer.valueOf(sss);

if(temp>100){

}

}catch (Exception e) {

logger.error(Catch an exception!, e);

}

}

18、NP_ALWAYS_NULL

18.1 缺陷说明

调用了可能为null的局部变量,可能会发生NullPointerException

18.2 代码示例

public void getStr(){

Date date = null;

int day = date.getDay();

}

18.3 解决方式

public void getStr(boolean flag){

Date date = new Date();

int day = date.getDay();

}

19、DLS_DEAD_LOCAL_STORE

19.1 缺陷说明

代码中定义未被使用的局部变量,建议将未使用的变量从代码中去除。

19.2 代码示例

public int exec(){

int rx = 100;

int ry = 200;

int local = (rx*ry)+100;

return 0;

}

List detailList = new ArrayList();

detailList = resultModel.getDetails();

19.3 解决方式

public int exec() {

int rx = 100;

int ry = 200;

int local = (rx*ry)+100;

return local;

}

List detailList;

detailList = resultModel.getDetails();

20、ES_COMPARING_PARAMETER_STRING_WITH_EQ

20.1 缺陷说明

使用==或者!=来比较字符串会比较两个字符串对象的内存地址,通常这是不一样的,

如果是想比较值的话通过equals(Object)来比较

20.2 代码示例

String firstKey;

if (firstKey != null && firstKey !=) {

System.out.println(wrong);

}

20.3 解决方式

String firstKey;

if (firstKey != null && firstKey.equals("")) {

System.out.println("right");

}

21、EVE_EXCEPTION_PRINT

21.1 缺陷说明

代码不能调用错误堆栈的打印方法,请使用SLF4J形式输出

21.2 代码示例

try {

} catch (Exception e) {

e.printStackTrace();

}

21.3 解决方式

try {

} catch (Exception e) {

LOGGER.info(输入日志信息));

}

22、CJ_SYSTEMCLASS

22.1 缺陷说明

代码不能出现System.out,请使用log形式输出

22.2 代码示例

22.3 解决方式

23、RE_POSSIBLE_UNINTENDED_PATTERN

23.1 缺陷说明

这个检测器会找出代码中用split方法传递的参数是正则表达式,

用到的字符('.' '|')没有转义的情况

23.2 代码示例

public static void main(String srds[]){

String ipstring=111.112.1113.22;

String iparray[]=ipstring.split(.);

for(String stemp:iparray){

System.out.println(stemp);

}

}

23.3 解决方式

public static void main(String srds[]){

String ipstring=111.112.1113.22;

String iparray[]=ipstring.split(//.);

for(String stemp:iparray){

System.out.println(stemp);

}

}

24、EC_UNRELATED_TYPES

24.1 缺陷说明

这个检测器会找出代码中用equals方法比较不同类型的情况,用equals方法比较不同类型都是返回false

24.2 代码示例

public static void main(String srgs[]){

String a=;

StringBuffer b=new StringBuffer();

if(a.equals(b))

System.out.print(It is false);

}}

24.3 解决方式

public static void main(String srgs[]){

String a=;

StringBuffer b=new StringBuffer();

String c= b.toString() ;

if(a.equals(c) )

System.out.print(It is true);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值