如何为lambda记录一个人类可读的字符串



我会尽量在这里非常小心我的措辞,因为lambda本质上只是一个方法签名和主体。

我的问题的前提是,它将是非常有用的,能够保持简洁的语法lambda,并能够有一个人类可读的名称(字符串)来识别它,即当你注销它。

以前,对于匿名类,我总是可以重写toString。

final Runnable runnable = new Runnable() {  
  @Override public void run() { System.out.println("1"); }
  @Override public String toString() { return "anonymous-1"; }
}
<<p> 场景/strong>

以下是我发现自己需要还原到代码才能破译

的场景
  1. 这种用法的一个场景是,你有一个lambda参数给另一个函数,在你的日志中,你希望能够打印出正在传递的特定lambda/实现。比如说,你有一个Consumer,它取一个String,你有这个的实现,它会打印出一个问候语加上一些语言的字符串。最好给策略命名,比如"用法语"、"用西班牙语"。
  2. 你有一组可运行的语句,每个语句依次应用,你想注销该集合的内容。

由于没有附带的toString,所以当您尝试注销lambda引用时,您在日志中得到的所有内容,例如:

MyClass$$Lambda$1/424058530@1c20c684

方法

  1. 我想你总是可以在lambda和捕获中引用一个记录器,这样当lambda执行时,你可以打印一个静态字符串来标识该lambda。
  2. 放弃lambda的优点,并恢复到匿名类…可以说鱼与熊掌不可兼得。

欣赏人们在这方面的想法和经历。

这里有一个中间地带,它在语法上比回到内部类更加紧凑——一个runable -with- tostring工厂。

static Runnable makeRunnable(Runnable r, Supplier<String> toStringFn) {
    return new Runnable() {
        public void run() { r.run(); }
        public String toString() { return toStringFn.get(); }
    };
}

现在,在使用站点,你做:

Runnable r = makeRunnable(() -> System.out.println("1"), 
                          () ->  "anonymous-1");

(如果您没有理由相信toString方法需要访问任何状态,您可以将第二个参数转换为String而不是Supplier<String>。)

最新更新