从VIP-sonar检测结果看常见代码问题--持续更新
前言
项目稳定之后,开始逐步关注过去赶进度写的“坏”代码问题,唯品会内部订制的sonar检测规则,在每次上线的时候都会进行静态代码检查,这阵子抽空看了自己项目的代码问题,同时也看了很多别的项目的检测结果,还是挺有收获,记录下。
代码细节
1.boxed and unboxed
拆箱跟装箱,是在sonar检测结果中见过最多的,正如sonar所提示 Be aware that this boxing happens automatically when you might not expect it. 很多没必要的装箱拆箱操作都是在你无意间发生的。比如:
Long data = Long.parseLong("123");
Long.parseLong(XXX) 返回的是long,而结果声明的是Long,所以无意间又触发了装箱
同样,反过来的有valueOf方法
long data = Long.valueOf("123");
这个问题是在看了几个项目的sonar结果中最常见的一个,比较多的场景是在用到方法调用参数上,例如方法的参数声明为 long, 而调用的时候是传Long,这样不仅有拆箱的操作,而且有NPE的可能性。
2.Files.newInputStream(myfile.toPath()) and new FileInputStream
创建FileInputStream对象,在使用new FileInputStream方式中,FileInputStream实现了finalize方法,这意味着创建的对象可能会一直挂起,直到发生gc,这意味着该对象在堆上的垃圾过多的时间更长。在java 7 中提供了NIO方式去创建,
InputStream is = java.nio.file.Files.newInputStream(myfile.toPath());
该方法返回的是 new sun.nio.ch.ChannelInputStream, ChannelInputStreamm没有实现finalize方法,就不会有上面那种问题。类似的还有FileOutputStream
3.静态变量和成员变量命名
一个类出现2个或多个变量几乎一样,除了大小写有区分外,可见性、命名几乎一样,这样让用户会感到非常困惑。比如:
private final static String COMMENT = "comment";
private String comment;
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
处理的时候建议修改COMMENT变量的名字,因为修改 comment变量会导致破坏调用方。
4.Stream漏了close
在处理输入流的时候大家都会注意在finally块close掉,但是可能会有漏掉的。比如:
InputStream stream = null;
InputStreamReader inputStreamReader = null;
BufferedReader reader = null;
try {
...
inputStreamReader = new InputStreamReader(stream, "UTF-8");
reader = new BufferedReader(inputStreamReader);
...
} finally {
if(reader != null){
reader.close();
}
}
只close掉 bufferReader,往往就忘记close InputStream 了
5.SimpleDateFormat线程安全问题
在通过静态属性获取SimpleDateFormat的实例进行调用,在使用上会有线程安全问题,本质上是因为parse方法的过程会有一个 Calendar.clear(重置日期对象cal的属性值),在多线程情况下可能会导致A线程 parse过程被B线程clear掉,导致错误。
public class Test {
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
public void test() {
simpleDateFormat.parse(XXX)
}
}
可以每个线程new 一个SimpleDateFormat对象,或者用ThreadLocal,或者直接使用common-lang的工具类。
6.indexOf 单个字符,使用单引号字符
在字符串获取某个字符的index的时候,采用单引号的写法,即字符,会比单字母的字符串效率会更高
addr.indexOf("A")
addr.indexOf('A')
–未完待续