java函数判断打印_关于打印debug日志是否加判断日志级别的分析

一、问题由来

在代码中,我们经常会看到打印debug日志的时候,会判断下当前的日志级别:

if (LOGGER.isDebugEnabled()) {

LOGGER.debug(... ...);

}

到底有没有必要呢?到底有没有必要呢?到底有没有必要呢

二、答案

为了节省大家的时间,先上答案。

1、如果打印的实参不含计算的,【完全没有必要】

String demo = "demo";

LOGGER.debug("i am a {}", demo); // 实参为: i am a {} 和demo两个

2、如果打印的实参含有计算的,【完全有必要】

Demo demo = new Demo();

LOGGER.debug("i am a " + "demo"); // 实参为: i am a demo,需要先进行实参计算

LOGGER.debug("i am a {}", demo.toString()); // 实参为:i am a {} 和demo.toString(),后者需要计算

三、实验探究

1、Log4j 源码

debug()方法中,一开始就做了和isDebugEnabled()一样的事情,那是不是就不需要判断了?

public boolean isDebugEnabled() {

if(repository.isDisabled( Level.DEBUG_INT))

return false;

return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());

}

public void debug(Object message) {

if(repository.isDisabled(Level.DEBUG_INT))

return;

if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {

forcedLog(FQCN, Level.DEBUG, message, null);

}

}

2、Log4j的占位符

网上的博客存在大量的分析,说开启了占位符{},完全不用判断。真的是这样吗?

// 虽然不会输出日志,但是demo.toString()确实是执行了

LOGGER.debug("{} {}", "a", demo.toString());

3、Java编译器的实参执行顺序:实参从左到右,最后是执行方法

这问题其实和log4j的关系不大,真正的原因是实参的执行顺序以及计算。😅

public class Test {

public static String fun1() { System.out.println("fun1"); return "fun1 "; }

public static String fun2() { System.out.println("fun2"); return "fun2"; }

public static void test(String s1, String s2) { System.out.println(s1 + s2); }

public static void main(String[] args) {

test(fun1(), fun2());

}

}

// console:

fun1

fun2

fun1 fun2

结论:打印debug日志,如果需要打印的数据需要计算实参的,必须加判断。这是因为不管debug()里面具体执不执行,实参的方法调用确实是执行了。

不好的例子:

LOGGER.debug("a" + "b");

LOGGER.debug("" + JSON.toJSONString(demo));

LOGGER.debug("{}", JSON.toJSONString(demo));

好的例子:

LOGGER.debug("{} {}","a","b");

LOGGER.debug("{}", demo);

4、结论

如果debug()里面的含有实参计算的,必须加判断。

推荐一种JSON序列化对象的方式:

public class Log {

@Override

public String toString() {

System.out.println("toString");

return JSON.toJSONString(this);

}

}

public class Test {

private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);

public static void main(String[] args) {

Log log = new Log();

LOGGER.debug("{}", log); // 实际运行时才会调用其toString()方法 - JSON方法

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值