出于调试目的,我试图Predicate在Java 8中创建lambda表达式的字符串表示(特别是s,尽管对其他lambda表达式也很有趣).我的想法是这样的:
public class Whatever {
private static <T> String predicateToString(Predicate<T> predicate) {
String representation = ... // do magic
return representation;
}
public static void main(String[] args) {
System.out.println(Whatever.<Integer>predicateToString(i -> i % 2 == 0));
}
}
Run Code Online (Sandbox Code Playgroud)
输出将是i -> i % 2 == 0(或逻辑等价的东西).这个toString()方法似乎没有任何帮助,输出就是这样的com.something.Whatever$$Lambda$1/1919892312@5e91993f(我想这是预期的,因为toString()它没有被覆盖).
我不确定这样的事情是否可能,例如反射,到目前为止我当然无法找到任何东西.有任何想法吗?
我不希望有一个正常的lambda实现一个方法,并重新定义它的toString作为一个附加值.我希望lambda表达式只实现toString方法.我知道我的表达不是很好,但我相信你会用这个例子来理解我.
public class LambdaToStringTest {
public interface ToStringInterface {
public abstract String toString();
}
public static void main(String[] args) {
print("TRACE: %s", (ToStringInterface)()->someComputation()); // <<-- ERROR: The target type of this expression must be a functional interface
}
private static void print(String format, Object... args) {
System.out.println(String.format(format, args));
}
}
Run Code Online (Sandbox Code Playgroud)
如果我更改方法的名称但它不会覆盖toString,则编译,因此print方法不会打印预期的内容.
这是尝试定义一个日志子系统,该子系统仅在需要时(当它真的要打印时)评估lambda,但与非lambda参数兼容.我知道其他方法来实现它,但我想知道为什么我不能这样做,如果有一个解决方法或我做错了什么,
我会在这里尝试用我的措辞非常小心,因为lambda本质上只是一个方法签名和正文.
我的问题的前提是,能够保持简洁的语法lambda,并且能够使用人类可读的名称(字符串)来识别它,即当您将其注销时,这将非常有用.
以前,使用匿名类我总是可以覆盖toString.
final Runnable runnable = new Runnable() {
@Override public void run() { System.out.println("1"); }
@Override public String toString() { return "anonymous-1"; }
}
Run Code Online (Sandbox Code Playgroud)
方案
以下是我发现自己需要恢复代码以便能够消除的情况
问题 因为没有附带toString,所以当你尝试注销lambda引用时,你会在日志中获得所有内容,例如:
MyClass$$Lambda$1/424058530@1c20c684
Run Code Online (Sandbox Code Playgroud)
途径
欣赏人们在此期间及其周围的想法和经验.