创建lambda表达式的字符串表示

出于调试目的,我试图在Java 8中创建lambda表达式的字符串表示(特别是Predicate s,尽管它对其他lambda表达式也很有意义)。我的想法是这样的:

 public class Whatever { private static  String predicateToString(Predicate predicate) { String representation = ... // do magic return representation; } public static void main(String[] args) { System.out.println(Whatever.predicateToString(i -> i % 2 == 0)); } } 

输出将是i -> i % 2 == 0 (或逻辑等价的东西)。 toString()方法似乎没有任何帮助,输出就像com.something.Whatever$$Lambda$1/1919892312@5e91993f (我想这是因为toString()没有被覆盖)。

我不确定这样的东西是否可能,例如reflection,到目前为止我当然无法找到任何东西。 有任何想法吗?

我能想到的最简单的事情是创建一个“命名谓词”,为谓词提供一个名称或描述,基本上任何可用作toString

 public class NamedPredicate implements Predicate { private final String name; private final Predicate predicate; public NamedPredicate(String name, Predicate predicate) { this.name = name; this.predicate = predicate; } @Override public boolean test(T t) { return predicate.test(t); } @Override public String toString() { return name; } public static void main(String... args) { Predicate isEven = new NamedPredicate<>("isEven", i -> i % 2 == 0); System.out.println(isEven); // prints isEven } } 

可以给出你的谓词名称或这样的描述,使你使用它们的代码也更容易理解:

 Stream.of(1, 2, 3, 4) .filter(isEven) .forEach(System.out::println); 

一个陌生人的想法可能是导出谓词的“结构”描述,即某些给定输入的输出是什么? 显然,当输入集有限且很小时(例如对于枚举,布尔值或其他一些限制集),这将最有效,但我想你也可以为整数谓词尝试一小组“随机”整数:

 private static Map> testPredicate(Predicate predicate) { return Stream.of(-35, -3, 2, 5, 17, 29, 30, 460) .collect(Collectors.partitioningBy(predicate)); } 

对于isEven ,这将返回类似{false=[-35, -3, 5, 17, 29], true=[2, 30, 460]} isEven {false=[-35, -3, 5, 17, 29], true=[2, 30, 460]} ,我认为不一定比手动给出更清晰它们是描述,但对于不受您控制的谓词可能有用。