我正在尝试检查使用了什么调用动态
http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
public class HelloWorld {
public static void main(String[] args) {
GreetingLambda lamda=()->System.out.println("Hello");
lamda.greet();
GreetingLambda lamda2=()->System.out.println("Hello");
lamda2.greet();
}
}
interface GreetingLambda{
void greet();
}
相同的字节码
public class HelloWorld {
/* compiled from HelloWorld.java */
/* inner class */
/* public final static Lookup */
public HelloWorld() {
/* L2 */
0 aload_0; /* this */
1 invokespecial 8; /* java.lang.Object() */
4 return;
}
void print(GreetingLambda arg0) {
/* L5 */
0 aload_1; /* l */
1 invokeinterface 16 1; /* void greet() */
/* L6 */
6 return;
}
public static void main(java.lang.String[] args) {
/* L10 */
0 invokedynamic 27; /* GreetingLambda greet() */
3 nop;
4 nop;
5 astore_1; /* lamda */
/* L11 */
6 aload_1; /* lamda */
7 invokeinterface 16 1; /* void greet() */
/* L12 */
12 invokedynamic 28; /* GreetingLambda greet() */
15 nop;
16 nop;
17 astore_2; /* lamda2 */
/* L13 */
18 aload_2; /* lamda2 */
19 invokeinterface 16 1; /* void greet() */
/* L17 */
24 return;
}
private static void lambda$0() {
/* L10 */
0 getstatic 34; /* java.lang.System.out */
3 ldc 40; /* "Hello" */
5 invokevirtual 42; /* void println(java.lang.String arg0) */
8 return;
}
private static void lambda$1() {
/* L12 */
0 getstatic 34; /* java.lang.System.out */
3 ldc 40; /* "Hello" */
5 invokevirtual 42; /* void println(java.lang.String arg0) */
8 return;
}
}
对lambda表达式的调用已被 invokedynamic 代替。但是我无法理解使用这种方法的好处。
List<String> a = new ArrayList<String>() ;
最佳答案
对于第一个问题:
简单地说:invokedynamic的设计非常仔细(因此花了很长时间才将其导入Java);这样做的副作用之一是明智的高效性能。
有关更多阅读,请参见here。从那里报价:
invokedynamic通过支持动态更改的调用站点目标,也使动态语言实现者受益-调用站点,更具体地说,动态调用站点是invokedynamic指令。此外,由于JVM内部支持invokedynamic,因此JIT编译器可以更好地优化此指令。
因此,长话短说:至少从理论上讲,当您可以编写使用invokedynamic而非使用解决某些问题的“老派”方式的代码时,新的invokedynamic解决方案一定会有“更快”的机会。如图所示:与使用老式的创建匿名内部类并使用它的方式相比,使用invokedynamic更快。