在日志打印时,多数是推荐使用占位符来进行参数的设置的,今天使用sonarqube扫描代码时,发现一些日志打印时的占位符与参数数量不匹配的问题,很多都是占位符数量多于参数数量,我便产生了疑惑,如果数量不匹配,占位符没有赋值的位置会怎么显示,于是便敲了一个小demo验证一下,结果如图:
在这里插入图片描述
上图是占位符数量与参数数量一致时,打印结果是正常的,下面测试一下缺少一个参数时:
在这里插入图片描述
结果显示没有进行赋值,这里只是缺少最后一个参数,所以其他位置的参数与占位符是对应的,如果缺少的是前边的参数呢(简单粗暴的办法就是直接在对应参数位置上添加一个“”空字符串,这样打印出来也不会混乱),势必会造成参数与占位符的混乱,如何解决占位符与参数的对应关系呢?我想到用数组,当使用数组时,只需要对相应位置的参数进行设置,如果中间某个位置未赋值,占位符则会取到null,这样就不会影响其他占位符的使用了,我的验证过程如图:
在这里插入图片描述
总结:在参数赋值时使用数组其实和在空参数位置直接使用null或者空字符串一样,因为Java中不定参数的实质就是将参数放进一个String字符串数组中,所以在上述的验证过程中,使用数组或者不使用数组意义不大,只是说提供了这样的方式,但是还是使用null或者空字符串这样的方式更加简单粗暴_

对于占位符的使用了解之后,以为什么时候都可以用了吗,这不就遇到一个坑:
当使用error或者warn级别的时候,如果想要把异常信息打印出来,使用占位符就不太合适了。
先看一下error的源码:
在这里插入图片描述
如图,当error中只有一个参数的时候,默认是String类型,所以如果使用logger.error(e.toString());这时候只会输出 [main] ERROR com.example.demo.DemoMain.logErrorDemo - java.lang.ArrayIndexOutOfBoundsException: 4的错误信息,并不能详细的展示错误的内容;
当使用两个参数,并且第一个参数中使用占位符的时候:
在这里插入图片描述

logger.error("使用占位符 {}",e);

输出结果是:
在这里插入图片描述
占位符失效,不过也输出了异常信息;通过查看源码,发现调用的并非是public void error(String format, Object arg);而是调用的public void error(String msg, Throwable t);所以猜测新版本应该会自动识别第二个参数的类型,如果是一个对象(dto),则会调用toString方法打印,但是如果是一个异常,则会调用public void error(String msg, Throwable t);方法。
在这里插入图片描述
使用上述方法时,打印异常方法:logger.error("使用,:",e);
这样的方式可以将异常的详细信息打印出来,异常内容
在这里插入图片描述
接着看多个参数的时候:
在这里插入图片描述
这个时候又会输出什么呢?
重点重点!!
当使用
在这里插入图片描述
当异常信息作为最后一个参数的时候,输出:
在这里插入图片描述
异常信息也是正常打印出来,但是源码显示这是的异常信息是一个object对象,看来和上面单独使用占位符一样,会自动将异常信息归为Throwable对象;
当异常信息不放在最后的时候呢?
在这里插入图片描述
这时候的输出:
在这里插入图片描述
我们发现这时候的异常信息就不完整了,所以通过实践,得出结论:
当使用error或者warn级别打印异常时,只要将异常信息作为最后一个参数,不论使用还是不使用占位符,都不会影响异常信息的输出,只不过占位符不会生效。
以上实验基于slf4j-1.7.30版本,根据别人反馈,使用1.6之前的版本的时候,由于异常信息使用String.format格式化msg,并不会将所有的异常堆栈信息打印出来,所以在使用时,考虑到旧版本的问题,最好还是使用logger.error("使用,:",e);的形式打印异常信息!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐