java 8调用动态优势

时间:2017-01-09 13:40:09

标签: java lambda

我正在尝试检查使用什么调用动态 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 取代。但是我无法理解使用这种方法有什么好处。

  1. invokedynamic 如何比匿名类生成更有用或更好。
  2. 它与从下面的代码生成的invokeinterface有什么不同,因为它也在进行运行时检查。

                       List<String> a = new ArrayList<String>() ;
    

2 个答案:

答案 0 :(得分:2)

对于第一个问题:

简单地说:invokedynamic经过精心设计(因此花了很长时间才能将它变成Java);其中一个副作用是:性能非常高效。

有关详细信息,请参阅here。引自那里:

invokedynamic还通过支持动态更改的呼叫站点目标(动态站点目标,更具体地说,动态呼叫站点是invokedynamic指令)使动态语言实现者受益。此外,由于JVM内部支持invokedynamic,因此JIT编译器可以更好地优化该指令。

所以,长话短说:至少在理论上,当你可以编写使用invokedynamic的代码而不是某些&#34;旧学校&#34;解决同样问题的方法,新的invokedynamic解决方案有一定的机会更快&#34;。如下所示:与创建匿名内部类的旧式方法相比,使用invokedynamic更快,并使用它。

答案 1 :(得分:2)

您引用的同一篇博客还有更多关于jruby优化的文章。例如here,Charles Nutter正在讨论invokedynamic的优点。

简而言之,它是一种优化,它允许jvm缓存和优化本来会混乱的方法句柄查找和间接。另一个优点是生成的代码对热点优化器更友好,这意味着许多使用java字节码的优化现在也适用于使用invokedynamic的jruby和其他jvm语言。

该功能专门添加到jvm以支持动态语言,其中绑定方法句柄的确切代码在运行时才知道(与静态语言不同)。