具有惰性求值的 String.format

2022-09-01 19:51:59

我需要类似于String.format(...)方法的东西,但带有惰性求值。

这个 lazyFormat 方法应该返回一些对象,然后 toString() 方法将计算格式模式。

我怀疑有人已经这样做了。这在任何图书馆中都可用吗?

我想替换这个(记录器是log4j实例):

if(logger.isDebugEnabled() ) {
   logger.debug(String.format("some texts %s with patterns %s", object1, object2));
}

有了这个:

logger.debug(lazyFormat("some texts %s with patterns %s", object1, object2));

我需要 lazyFormat 来格式化字符串,前提是启用了调试日志记录。


答案 1

如果您正在寻找一个“简单”的解决方案:

 public class LazyFormat {

    public static void main(String[] args) {
        Object o = lazyFormat("some texts %s with patterns %s", "looong string", "another loooong string");
        System.out.println(o);
    }

    private static Object lazyFormat(final String s, final Object... o) {
        return new Object() {
            @Override
            public String toString() {
                return String.format(s,o);
            }
        };
    }
}

输出:

一些文本 looong 字符串与模式另一个 loooong 字符串

如果你愿意,你当然可以在lazyFormat中添加任何语句。isDebugEnabled()


答案 2

可以通过在最新的log4j 2.X版本中使用参数替换来完成,http://logging.apache.org/log4j/2.x/log4j-users-guide.pdf

4.1.1.2 参数替换

通常,日志记录的目的是提供有关系统中发生的情况的信息,这需要包括有关正在操作的对象的信息。在Log4j 1.x中,这可以通过执行以下操作来完成:

if (logger.isDebugEnabled()) {     
  logger.debug("Logging in user " + user.getName() + " with id " + user.getId()); 
} 

反复这样做会使代码感觉更像是日志记录,而不是手头的实际任务。此外,它还会导致日志记录级别被检查两次;一次在调用 isDebugEnabled 时,一次在 debug 方法上。更好的选择是:

logger.debug("Logging in user {} with id {}", user.getName(), user.getId()); 

如果代码高于该级别,则只会检查日志记录一次,并且只有在启用调试日志记录时才会发生 String 构造。