异常日志
异常处理
- 【强制】finally 块必须对资源对象、流对象进行关闭操作,如果有异常也需要 try-catch。
说明:对于 JDK7 及以上版本,可以使用 try-with-resources 方式(只是一种语法形式,原理同样是在 finally 中进行外部资源释放)File file = new File("E:\\test.txt"); int len = (int) file.length(); byte[] buffer = new byte[len]; try (FileInputStream inputStream = new FileInputStream(file)){ inputStream.read(buffer,0,len); System.out.println(new String(buffer, StandardCharsets.UTF_8)); }catch (IOException e){ e.printStackTrace(); } FileInputStream inputStream = null; try { inputStream = new FileInputStream(file); inputStream.read(buffer,0,len); } catch (IOException e) { e.printStackTrace(); } finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
-
【强制】不要 finally 块中使用 return。
说明:try 块中的 return 语句执行成功后,不会马上返回,而是继续执行 finally 块中的语句,如果在 finally 中 return,则在此直接返回,try 中的 返回点 被丢弃。 -
【强制】在调用 RPC、二方包或动态生成类的相关方法时,捕捉异常必须使用 Throwable 类来进行拦截。(所有异常和错误的超类)。
说明:通过反射机制来调用方法,如果找不到方法,抛出NoSuchMethodException。在什么情况下会抛出NoSuchMethodError呢?二方包在类冲突时,仲裁机制可能导致引入非预期的版本使类的方法签名不匹配,或者在字节码修改框架(比如:ASM)动态创建或修改类时,修改了相应的方法签名。这些情况,即使代码编译期正确,但在代码运行期间时,会抛出 NoSuchMethodError。 -
【推荐】产生 NPE 的场景:
1)当返回类型为基本数据类型,return 包装数据类型的对象,自动拆箱有可能产生 NPE。
反例:public int add() { retrun Integer 对象 },如果为 null,自动拆箱,抛 NPE。
2)数据库查询结果可能为 null。
3)集合里的元素即使 isNotEmpty ,取出的数据元素也可能为 null。
4)远程调用返回对象时,一律要求进行空指针判断,以防 NPE。
5)对于 Session 中获取的数据,建议进行 NPE 检查,避免空指针。
6)级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。
正例:使用 JDK8 的 Optional 类来防止出现 NPE 问题。 -
【参考】对于公司外的 HTTP/API 开放接口必须使用“错误码”;应用内部推荐异常抛出;跨应用 RPC 调用优先考虑是使用 Result 方式,封装 isSuccess() 方法、“错误码”、“错误简短信息”。
日志规约
- 【强制】在日志输出时,字符串变量之间的拼接使用占位符的方式。
说明:因为 String 字符串的拼接会使用 StringBuilder 的 append 方法,有一定的性能损耗。使用占位符仅是替换动作,可以有效提升性能。
正例:logger.debug("param:{},and symbol:{}",id,symbol);
- 【强制】避免重复打印日志,否则会浪费磁盘空间,务必在日志配置文件中设置 additivity=false。
正例:<logger name="com.taobao.dubbo.config" additivity="false">