一些经常出现的bug的地方
NPE空指针
基本类型 获取包装类型的结果
JSONObject jsonObj = …
boolean isFastigium = jsonObj.getBoolean(“fastigium”);
应该改为
boolean isFastigium = jsonObj.getBooleanValue(“fastigium”);将异常信息转为字节数组
exception.getMessage().getBytes(“UTF-8”);
.getMessage()定义在Throwable默认是nullThreadLocal初始化的地方错误
private static ThreadLocal<Boolean> isDebug = new ThreadLocal<Boolean>();
static {
isDebug.set(false);
}
这种初始化是无意义的 boolean = isDebug.get()会出现转换NPE
正确的初始化写法
private static ThreadLocal<Boolean> isDebug = new ThreadLocal<Boolean>(){
@Override
protected Boolean initialValue() {
return false;
}
};
clean codes会增加阅读性,有助于减少BUG
- 了解API设计者的意图
String studentSafeName = StringUtils.isBlank(studentUser.getName()) ? studentUser.getUsername() : studentUser.getName();
Object[] params = new String[]{
studentSafeName,
df.format(scheduledTime),
teacherUser.getName(),
lesson.getSerialNumber(),
lesson.getName()
};
String message = String.format(templateCancelMajor, params);
上面的代码比较啰嗦
查看相似API<String> String org.apache.commons.lang3.StringUtils.defaultIfBlank(String str, String defaultStr)
和查看具体的参数类型
String java.lang.String.format(String format, Object... args)
改写为下面
String name = StringUtils.defaultIfBlank(studentUserProfile.getName(), student.getEnglishName());
String message = String.format(templateBookedMajors, name, teacherUser.getName(), SDF.format(scheduledTime),
lesson.getSerialNumber(), lesson.getName());
2.选择合适的工具类,尽量让代码看起来干净
private long initData(List<Long> onlineClassIds) {
AtomicInteger fixCount = new AtomicInteger();
List<Future<Boolean>> futureTasks = new ArrayList<>();
onlineClassIds.forEach((id) -> {
Future<Boolean> future = executor.submit(() -> {
return dbyClassroomService.fixClassroomDocuments(id);
});
futureTasks.add(future);
});
futureTasks.forEach((future) -> {
try {
if (future.get()) {
fixCount.incrementAndGet();
}
} catch (Exception e) {
e.printStackTrace();
}
});
logger.info("fixCount={}, ", fixCount);
return fixCount.get();
}
改为
public int initData(List<Long> onlineClassIds) {
if (onlineClassIds.isEmpty()) {
return 0;
}
AtomicInteger fixCount = new AtomicInteger();
CountDownLatch latch = new CountDownLatch(onlineClassIds.size());
onlineClassIds.forEach(config -> {
executor.execute(() -> {
// ...
fixCount.incrementAndGet();
latch.countDown();
});
});
try {
latch.await();
} catch (InterruptedException e) {
logger.error("latch.await err:{},", e);
}
logger.info("all inited time used{},", fixCount);
return fixCount.get();
}