java编程常见错误四[转帖]_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3684 | 回复: 0   主题: java编程常见错误四[转帖]        下一篇 
lynda
注册用户
等级:上尉
经验:570
发帖:49
精华:0
注册:2012-8-7
状态:离线
发送短消息息给lynda 加好友    发送短消息息给lynda 发消息
发表于: IP:您无权察看 2012-8-8 17:18:37 | [全部帖] [楼主帖] 楼主

用日志记录异常

错误的写法:

  1. try {   
  2.  ...   
  3. } catch(ExceptionA e) {   
  4.  log.error(e.getMessage(), e);   
  5.  throw e;   
  6. } catch(ExceptionB e) {   
  7.  log.error(e.getMessage(), e);   
  8.  throw e;   

一般情况下在日志中记录异常是不必要的, 除非调用方没有记录日志。

异常处理不彻底

错误的写法:

  1. try {   
  2.  is = new FileInputStream(inFile);   
  3.  os = new FileOutputStream(outFile);   
  4. } finally {   
  5. try {   
  6.  is.close();   
  7.  os.close();   
  8. } catch(IOException e) {   
  9.  /* we can't do anything */   
  10. }   

is可能close失败, 导致os没有close

正确的写法:

  1. try {   
  2.  is = new FileInputStream(inFile);   
  3.  os = new FileOutputStream(outFile);   
  4. } finally {   
  5. try { if (is != null) is.close(); } catch(IOException e) {/* we can't do anything */}   
  6. try { if (os != null) os.close(); } catch(IOException e) {/* we can't do anything */}   

捕获不可能出现的异常

错误的写法:

  1. try {   
  2.  ... do risky stuff ...   
  3. } catch(SomeException e) {   
  4.  // never happens   
  5. }   
  6. ... do some more ... 

正确的写法:

  1. try {   
  2.  ... do risky stuff ...   
  3. } catch(SomeException e) {   
  4.  // never happens hopefully   
  5.  throw new IllegalStateException(e.getMessage(), e); // crash early, passing all information   
  6. }   
  7. ... do some more ... 

transient的误用

错误的写法:

  1. public class A implements Serializable {   
  2.  private String someState;   
  3.  private transient Log log = LogFactory.getLog(getClass());   
  4.  
  5.  public void f() {   
  6.  log.debug("enter f");   
  7.  ...   
  8.  }   

这里的本意是不希望Log对象被序列化. 不过这里在反序列化时, 会因为log未初始化, 导致f()方法抛空指针, 正确的做法是将log定义为静态变量或者定位为具备变量。

正确的写法:

  1. public class A implements Serializable {   
  2.  private String someState;   
  3.  private static final Log log = LogFactory.getLog(A.class);   
  4.  
  5.  public void f() {   
  6.  log.debug("enter f");   
  7.  ...   
  8.  }   
  9. }   
  10. public class A implements Serializable {   
  11.  private String someState;   
  12.  
  13.  public void f() {   
  14.  Log log = LogFactory.getLog(getClass());   
  15.  log.debug("enter f");   
  16.  ...   
  17.  }   

不必要的初始化

错误的写法:

  1. public class B {   
  2.  private int count = 0;   
  3.  private String name = null;   
  4.  private boolean important = false;   

这里的变量会在初始化时使用默认值:0, null, false, 因此上面的写法有些多此一举。

正确的写法:

  1. public class B {   
  2.  private int count;   
  3.  private String name;   
  4.  private boolean important;   

最好用静态final定义Log变量

  1. private static final Log log = LogFactory.getLog(MyClass.class);  

这样做的好处有三:

  • 可以保证线程安全
  • 静态或非静态代码都可用
  • 不会影响对象序列化

选择错误的类加载器

错误的代码:

  1. Class clazz = Class.forName(name);   
  2. Class clazz = getClass().getClassLoader().loadClass(name);  

这里本意是希望用当前类来加载希望的对象, 但是这里的getClass()可能抛出异常, 特别在一些受管理的环境中, 比如应用服务器, web容器, Java WebStart环境中, 最好的做法是使用当前应用上下文的类加载器来加载。

正确的写法:

  1. ClassLoader cl = Thread.currentThread().getContextClassLoader();   
  2. if (cl == null) cl = MyClass.class.getClassLoader(); // fallback   
  3. Class clazz = cl.loadClass(name);  

反射使用不当

错误的写法:

  1. Class beanClass = ...   
  2. if (beanClass.newInstance() instanceof TestBean) ...  

这里的本意是检查beanClass是否是TestBean或是其子类, 但是创建一个类实例可能没那么简单, 首先实例化一个对象会带来一定的消耗, 另外有可能类没有定义默认构造函数. 正确的做法是用Class.isAssignableFrom(Class) 方法。

正确的写法:

  1. Class beanClass = ...   
  2. if (TestBean.class.isAssignableFrom(beanClass)) ...  




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论