Java编程中最容易忽略的10个常见问题(1)(2)
4. 日志跑哪了?
现象
有时候觉得log都打了,怎么找不到?
示例一:没有stack trace!
} catch (Exception ex) {
log.error(ex);
}
示例二:找不到log!
} catch (ConfigurationException e) {
e.printStackTrace();
}
解决
启示
5. 遗忘的Volatile
现象
在DCL模式中,总是忘记加一个Volatile。
private static CacheImpl instance; //lose volatile
public static CacheImpl getInstance() {
if (instance == null) {
synchronized (CacheImpl.class) {
if (instance == null) {
instance = new CacheImpl ();
}
}
}
return instance;
}
解决
毋庸置疑,加上一个吧,synchronized 锁的是一块代码整个方法或某个代码块),保证的是这”块“代码的可见性及原子性,但是instance == null第一次判断时不再范围内的。所以可能读出的是过期的null。
启示
我们总是觉得某些低概率的事件很难发生,例如某个时间并发的可能性、某个异常抛出的可能性,所以不加控制,但是如果可以,还是按照前人的“最佳实践”来写代码吧。至少不用过多解释为啥另辟蹊径。
6. 不要影响彼此
现象
在释放多个IO资源时,都会抛出IOException ,于是可能为了省事如此写:
public static void inputToOutput(InputStream is, OutputStream os,
boolean isClose) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is, 1024);
BufferedOutputStream bos = new BufferedOutputStream(os, 1024);
….
if (isClose) {
bos.close();
bis.close();
}
}
假设bos关闭失败,bis还能关闭吗?当然不能!
解决办法
虽然抛出的是同一个异常,但是还是各自捕获各的为好。否则第一个失败,后一个面就没有机会去释放资源了。
启示
代码/模块之间可能存在依赖,要充分识别对相互的依赖。

用户点评