【发布时间】:2017-02-27 03:54:25
【问题描述】:
如果你有一个像这样的匿名类
Predicate<String> isEmpty = new Predicate<String>() {
public boolean test(String t) {
return t.isEmpty();
}
};
通过对isEmpty 的引用的库可以检查字节码以查看它的作用并可能对其进行操作。有没有办法为 lambdas 做到这一点?
Predicate<String> isEmpty = String::isEmpty;
例如说有这个代码和字节码
public class Main {
public static void test(Predicate<String> tester) {
System.out.println("tester.getClass()= " + tester.getClass());
System.out.println("tester.getClass().getClassLoader()="+ tester.getClass().getClassLoader());
}
public static void main(String... args) {
Predicate<String> isEmpty = String::isEmpty;
test(isEmpty);
}
}
$ javap -cp . -c -private Main.class
Compiled from "Main.java"
public class Main {
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void test(java.util.function.Predicate<java.lang.String>);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String tester.getClass()=
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_0
16: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class;
19: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
22: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
25: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
28: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
31: new #3 // class java/lang/StringBuilder
34: dup
35: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
38: ldc #11 // String tester.getClass().getClassLoader()=
40: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
43: aload_0
44: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class;
47: invokevirtual #12 // Method java/lang/Class.getClassLoader:()Ljava/lang/ClassLoader;
50: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
53: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
56: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
59: return
public static void main(java.lang.String...);
Code:
0: invokedynamic #13, 0 // InvokeDynamic #0:test:()Ljava/util/function/Predicate;
5: astore_1
6: aload_1
7: invokestatic #14 // Method test:(Ljava/util/function/Predicate;)V
10: return
}
在test 中引用tester 如何找到调用了哪个方法?
【问题讨论】:
-
通过方法引用,您可以查看引用了哪个方法,然后查找该方法的字节码。对于常规的旧 lambda,lambda 字节码应位于
lambda$#私有方法中。只需javap和-private选项。 -
您能澄清一下您要寻找的答案吗?字节码确实包含 lambdas 和方法引用的条目,所以,是的,您可以检查字节码。你问怎么做?
-
@SotiriosDelimanolis 是的。假设我有上面的例子。我参考了 isEmpty。如何找到此实例将调用的代码?
-
看来 BootstrapMethods 可能掌握着关键。这是这种情况/最好的方法吗?
-
可怜的赏金......不过,我很欣赏你的来宾;)
标签: java lambda java-8 bytecode