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(); }
- Java常见缺陷模式
- 常见活动对象缺陷
- Java 常见设计模式
- Java 常见设计模式
- JAVA常见设计模式
- java常见设计模式
- Java常见设计模式
- Java常见设计模式
- java常见的设计模式
- 常见的Java设计模式
- java开发常见设计模式
- java常见的设计模式
- 常见的Java设计模式
- buider模式的缺陷
- java线程的缺陷
- java线程的缺陷
- java线程的缺陷
- java线程的缺陷
- msfvenom
- 你所不知道的Python奇技淫巧
- 七层网络模型
- Java上机心得1
- Ubuntu 17.10 “Artful Aardvark” 发布首个 Beta
- Java常见缺陷模式
- 校门外的树
- 数学中的常见符号
- Python魔术方法详解
- POJ 1035.Spell checker
- Python--Virtualenv简明教程
- epoll触发事件的分析
- 阿里云CentOS 7 搭建图片服务器 (Nginx+Vsftpd)
- 史上最简单的SpringCloud教程 | 第九篇: 服务链路追踪(Spring Cloud Sleuth)