异样解决

  • Java类库中定义的能够通过预查看形式躲避的RuntimeException异样不应该通过catch形式来解决:

    • NullPointerException
    • IndexOutofBoundsException
    • 无奈通过预查看的异样除外: 在解析字符串模式数字时,不得不通过catch NumberFormatException来实现

      if (obj != null) {}
  • 异样不要用来做流程管制,条件管制:

    • 异样设计的初衷是解决程序运行中的各种意外状况,且异样的解决效率比条件判断形式要低很多
  • 应用catch时要辨别稳固代码和非稳固代码:

    • 稳固代码: 无论如何不会出错的代码
    • 非稳固代码: 非稳固代码的catch尽可能辨别异样类型,再做对应解决
    • 对于大段代码进行try - catch,会使得程序无奈依据不同的异样做出正确的应激反应,也不利于定位问题

      • 在用户注册场景中,如果用户输出非法字符,或者用户名称已存在,或者用户明码过于简略,在程序上作出分门别类的判断,并提醒给用户
  • 捕捉异样是为了解决,不要捕捉了什么都不解决.如果不须要解决,应该将异样抛给调用者

    • 最外层的业务使用者,必须解决异样,将其转化为用户能够了解的内容
  • 如果有try块放到了事务代码中 ,catch异样后,如果须要回滚事务,肯定要留神手动回滚事务
  • finally块必须对资源对象,流对象进行敞开,有异样也要做try - catch

    • JDK 7当前,能够应用try - with - resources 形式
  • 不要在finally块中应用return:

    • finally块中的return返回后办法完结执行,不会再执行try块中的return语句
  • 捕捉异样与抛出异样必须齐全匹配,或者是抛异样的父类
  • 办法的返回值能够为null,不强制返回空集合或者空对象等,必须增加正文充分说明什么状况下会返回null值

    • 即便调用办法返回空集合或者空对象,对于调用者来说,必须思考到近程调用失败,序列化失败,运行时异样等返回null的场景
  • 肯定要防止出现NPE异样,留神NPE产生的场景:

    • 返回类型为根本数据类型,return包装数据类型的对象时, 主动拆箱有可能产生NPE
    • 数据库的查问后果可能为null
    • 汇合里的元素即便isNotEmpty, 取出的数据元素也可能为null
    • 近程调用返回对象时,一律要进行空指针判断,避免NPE
    • 对于Session中获取的数据,倡议进行NPE查看,防止空指针
    • 级联调用obj.getA().getB.getC(), 一连串的调用,容易产生NPE
    • JDK 8应用Optional类来避免NPE问题
  • 定义时辨别uncheckedchecked异样,防止间接抛出new RuntimeException(), 不容许抛出Exception或者Throwable, 应该应用有业务含意的自定义异样

    • 举荐应用业务界已定义过的异样:

      • DAOException
      • ServiceException
  • 对于公司外的http或者api凋谢接口必须应用 "错误码"; 利用外部举荐异样抛出; 跨利用间的RPC调用优先思考应用Result形式,封装isSuccess()办法,错误码,谬误简短信息

    • RPC办法应用Result形式的起因:

      • 应用抛异样返回形式,调用方如果没有捕捉到就会产生运行时谬误
      • 如果不加栈信息,只是new自定义异样,退出本人了解的error message, 对于调用端解决问题的帮忙不会太多.如果加了栈信息,在频繁调用出错的状况下,数据序列化和传输的性能损耗也是问题
  • 避免出现反复的代码,即DRY(Don't Repeat Yourself)准则:

    • 反复的代码在当前的批改时,须要批改所有的正本,容易脱漏
    • 抽取共性办法,或者形象公共类,或者组件化

      • 一个类中有多个public办法,都须要进行数行雷同的参数校验工作,这个时候就要进行抽取:

        private boolean checkParam(DTO dto) {...}

        日志规约

  • 利用中不可间接应用日志零碎(log4j,logback)中的API,应该应用日志框架slf4j中的API, 应用门面模式的日志框架,有利于保护和各个类的日志解决形式对立
  • 日志文件至多保留15天,因为有些异样具备以 "周" 为频次产生的特点
  • 利用中的扩大日志(打点,长期监控,拜访日志等)命名形式:

    • appName_logType_logName.log

      • logType: 日志类型,如 stats,monitor,access
      • logName: 日志形容
      • 这样通过文件名就能够晓得日志文件属于什么利用,什么类型,什么目标,也不便归类查找

        • mppserver利用中独自监控时区转换异样: mppserver_monitor_timeZoneConvert.log
      • 对日志进行分类,比方将谬误日志和业务日志离开寄存,便于开发人员查看,也便于对日志零碎进行及时监控
  • trace,debug,info级别的日志输入,必须应用条件输入模式或者应用占位符形式

    logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);
    • 如果日志级别是warn: 上述日志不会打印,然而或执行字符串拼接操作
    • 如果symbol是对象,会执行toString() 办法,节约了系统资源,执行上述操作,最终日志却没有打印
    • 应用条件输入模式:

      if (logger.isDebugEnabled()) {  logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);}
    • 应用占位符输入模式:

      logger.debug("Processing trade with id: {} and symbol: {}, id, symbol);
  • 防止反复打印日志,节约磁盘空间,必须在log4j.xml中设置additivity=false

    <logger name="com.oxford.dubbo.config" additivity="false">
  • 异样信息包含:

    • 案发现场信息
    • 异样堆栈信息
    • 如果不解决,应该通过异样关键字throws向上抛出

      logger.error(各类参数或者对象toString() + "_" + e.getMessage(), e);
  • 审慎的记录日志:

    • 生产环境禁止输入debug日志
    • 有选择地输入info日志
    • 如果应用warn来记录刚上线时的业务行为信息,肯定要留神日志输出量问题,防止服务器内容过多,并及时删除这些察看日志

      • 大量地输入有效日志,不利于零碎性能的晋升,也不利于疾速定位谬误点
      • 记录日志时须要思考:

        • 这些日志真的有人看吗?
        • 看到这条日志可能做什么?
        • 能不能给排查问题带来益处?
  • 能够应用warn日志级别来记录用户输出参数谬误的状况
  • 留神日志的输入级别:

    • error级别只记录零碎逻辑出错,异样或者重要的错误信息
  • 应用全英文来正文和形容日志错误信息