Java常见缺陷模式

来源:互联网 发布:汽车保值率怎么算法 编辑:程序博客网 时间:2024/06/06 14:26

Java常见缺陷模式


指出下列各代码片段存在的缺陷,陈述你的理由并修改缺陷(共15题)

1.字符串相等问题

private void bug_method(String str){    if ( str == "Red")        dosthRed();    else        dosthBlack();}

错误:str==”Red”

改正:str.equals(“Red”)

2.相等判断错误

SomeObject cmpObj = new SomeObject();private boolean bug_method(SomeObject obj1){    //want to compare if the two object's value is same       return obj1 == cmpObj;}

错误:return obj1 == cmpObj

改正:代码想要比较两个对象是否相等并返回结果,但是直接采用了==运算符,==运算符是比较两个对象地址是否相等,理论上,只要obj1与cmpObj不是指向同一个堆中new对象那么return一定会返回false。这并不是我们想要的结果。在这道题目中说讲两个对象比较,说明这两个对象是有比较的概念的,所以应该实现该类继承自Object的equals方法。采用obj1.equals(cmpObj)的方法进行比较。

3.浮点数精度问题

public static double bugMethod(Func f, double x1, double x2) {    double x = x1;    double result = 0;    double step = (x2 - x1) / 700;    while (x != x2) {         result = result + f.valueFor(x) * step;        x = x + step;    }    return result;}

错误:while(x!=x2)

改正:浮点数精度有限,在step=(x2 - x1) / 700;这一步中很有可能不能整除导致step是一个很多小数位的浮点数,在此情况下用x+step更新的到的x值的精度大于或小于x2,导致循环不能正确结束,形成死循环,在代码中应该尽量避免用double做判断循环的条件。

4.&与&&区别

private void bugMethod(int arr[]){    if((arr!=null) & (arr.length < 10))        Dosomthing();}

缺陷:&

改正:&是按位与,a&b是把a和b都转换成二进制数然后再进行与的运算。&&是逻辑与,a&&b就是当且仅当两个操作数均为true时,其结果才为true,只要有一个为零,a&&b就为false。在这道题目中,理论上if中两个部分都会转换为boolean类型进行判断,此时&或&&都是正确结果,但是&与&&有根本意义上的区别,不建议使用&进行逻辑判断。

5.数组问题

public class  AClass{    Private int arr[];    Public void alloc(int length){        arr = new int[length];    }    Public int get(int index){        return arr[index];    }}           public class BugClass{    public static void main(String args[]){        AClass bug1 = new AClass();        AClass bug2 = new AClass();        bug1.alloc(10);        for(int i=0;i<=10;i++){            System.out.println(bug1.get(i));          System.out.println(bug2.get(i));       }    }}

错误:bug2数组没有alloc初始化

改正:调用bug2点alloc方法初始化数组,否则调用get会报错。

7.资源关闭

public List<Integer> getActiveIDs() throws SQLException {         Connection con = DriverManager.getConnection("http://");         Statement statement = con.createStatement();         ResultSet rs = statement.executeQuery("SELECT * FROM table");          final List<Integer> result = new ArrayList<Integer>();         while (rs.next()) {             if (rs.getBoolean("active")) {                 result.add(rs.getInt("id"));             }         }         return result;     }

缺陷:没有关闭所有打开的资源。

改正:

try{        Connection con = DriverManager.getConnection("http://");        Statement statement = con.createStatement();        ResultSet rs = statement.executeQuery("SELECT * FROM table");         final List<Integer> result = new ArrayList<Integer>();        while (rs.next()) {            if (rs.getBoolean("active")) {                result.add(rs.getInt("id"));            }        }        rs.close();        stmt.close();        conn.close();        return result;    }catch(Exception e){        e.printStackTrace();    }finally{      try{         if(stmt!=null)            stmt.close();      }catch(SQLException e2){      }      try{         if(conn!=null)            conn.close();      }catch(SQLException se){         se.printStackTrace();      }   }

8.空字符串与null

static String searchForMaxString(final String text) {         if (text == null) return null;         int max = 0;         StringTokenizer tok = new StringTokenizer(text, ":",true);         String found = null;         while (tok.hasMoreTokens()) {             String x = tok.nextToken();             if (x.length() >= max) {                 max = x.length();                 found = x;            }           }         int len = found.length();         System.err.println(len + " -> " + found);         return found;     }

错误:if (text == null) return null;

改正:if (text == null || text.length()==0) return null;如果输入String为“”,则found为null,进行found.length()操作会报错。

9.释放锁问题

void action() {            Lock l = new ReentrantLock();            l.lock();            try {               dosomething();            } catch (Exception e) {              l.unlock();        }     }

错误:catch (Exception e) {l.unlock();}

改正:finally {l.unlock();} 锁不应该在catch中释放,不是“如果没异常锁就无法释放”的问题,锁根本就不应该和catch有任何联系,永远记住finally释放锁。

11.synchronized问题

    public class MyClass {          public synchronized List getElements() {              return internalGetElements();          }          synchronized List internalGetElements() {              List list = new ArrayList();              // calculate and return list of elements              return list;          }         // ...      }

缺陷:这个代码可以运行,不会报错,list是局部变量不存在安全问题。全都使用synchronized可能写法不是很好。

改正:

    public class MyClass {          public synchronized List getElements() {              return internalGetElements();          }          private List internalGetElements() {              List list = new ArrayList();              // calculate and return list of elements              return list;          }         // ...      }

12.文件资源问题

 void configure(final String path) throws IOException {      BufferedReader in = null;         try {             in = new BufferedReader(new FileReader(path));         } catch (FileNotFoundException e) {            e.printStackTrace();         }        if (in == null) {             log("Was not able to access the file");             return;         }          String line;         while ((line = in.readLine()) != null) {             parseConfiguration(line);         }     }

缺陷:未关闭文件资源

改正:

try(FileReader fir = new FileReader(path);    BufferedReader br = new BufferedReader(fir)) {         } catch (FileNotFoundException e) {            e.printStackTrace();         }
原创粉丝点击