【发布时间】:2019-07-19 10:06:39
【问题描述】:
我经常看到这样的经典结构:
if (LOG.isLoggable(Level.FINER)) {
LOG.finer("The driver of the car is '"+ car.getDriver().getName() +"'.");
}
假设汽车没有司机,getDriver() 返回null。
LOG.finer 的实现可以在这里找到:http://developer.classpath.org/doc/java/util/logging/Logger-source.html#line.971
然后:
-
getName()不能在null上执行,所以会抛出 NPE。仅在一个特殊情况下:我必须在FINER上拥有记录器。 -
LOG.isLoggable必须执行两次,第一次在.finer(的方法调用之前,第二次在方法finer内。 - 在数学运算符
+上创建一个StringBuilder。 - 我必须导入类
Level。 - 不同的线程可以将驱动程序设置为
null并阻止日志记录此行。
如果我改用 Lambda 会怎样?
例子:
LOG.finer(()->"The driver of the car is '", ()->car.getDriver().getName(), ()->"'.");
finer 定义为
public void finer(ObjectReturningFunctionalInterface ... arguments) {
如果我们捕获所有参数评估异常,我们可以解决我们在经典样式中看到的所有缺点。
为什么这是个坏主意?
【问题讨论】:
-
我认为一个更好的主意,一个生成整个字符串的 lambda。从这个意义上说,任何可能需要创建成本(罕见,imo)的东西只有在使用关卡时才会生成。对单个字符串使用 varargs lambdas 似乎太过分了
-
@PeterRader 这些可能是事实,但问题标题可能会吸引意见。你列出的缺点有那么糟糕吗?在我看来,为了清楚起见,你应该坚持使用经典的方式而不是 3 个 lambda。在这种情况下,即使在记录之前检查日志级别也不是我会做的事情。大多数记录器框架已经允许您添加 lambda 以提供参数 btw。编辑:新标题没有太大变化。“更好”仍然是主观的,除非你明确你想要达到的目标(例如性能、可读性、避免空指针)
-
3 是不真实的。 1无论哪种方式都是一个问题。 2 是因为您的日志记录习语来自大约 5 年前,实际上没有人这样写日志记录。最后两点充其量似乎是虚假的。 TL;DR:使用一个不错的插值日志记录功能。
-
另外
logger.finer()已经存在!!您对多个 lambda 的建议几乎没有添加任何内容。 -
“由于性能原因,在进行日志记录之前检查日志记录级别”因为您使用了糟糕的日志记录框架。现代的插入到字符串常量中。没有开销(即字符串连接,
toString参数调用)。
标签: java logging lambda java-8