Java Lambdas:它如何在JVM中运行并且是OOP吗?

例如,在匿名内部类的情况下,传递(匿名)对象引用并执行该对象的方法。

Lambda是代码块,将在需要时执行。

遇到lambdas时JVM中会发生什么? JVM在哪里存储与lambdas相关的代码块(Heap:Young,Old或Permanent Generation)?

我尝试搜索,我得到了使用lambdas的语法但是无法理解JVM中发生的事情,因为在JAVA中一切都是基于对象的。

  1. 所以在OOP的背景下,lambda是如何工作的?

  2. lambda违反了OOP概念吗?

  3. Lambda是否适合垃圾收集器,因为没有创建对象因此不用担心内存问题和清​​除内存?

我不会浪费时间思考天气lambda表达式违反OO原则。 它的目标是增加语言的function而不是编写OO代码,我不知道lambdas如何违反封装,inheritance或多态。

本文解释了Java如何处理lambda表达式:

有关Lambda表达式的有趣之处在于,从JVM的角度来看,它们是完全不可见的。 它没有匿名函数或Lambda表达式的概念。 它只知道字节码是严格的OO规范。 由语言的制造者及其编译器在这些约束下工作以创建更新,更高级的语言元素。

考虑以下代码:

List names = Arrays.asList("1", "2", "3"); Stream lengths = names.stream().map(name -> name.length()); 

…它很简单地通过加载名称var并调用其.stream()方法开始,但它确实做了一些非常优雅的事情。 它不使用创建将包装Lambda函数的新对象,而是使用Java 7中添加的新invokeDynamic指令将此调用站点动态链接到实际的Lambda函数。

 aload_1 //load the names var // call its stream() func invokeinterface java/util/List.stream:()Ljava/util/stream/Stream; //invokeDynamic magic! invokedynamic #0:apply:()Ljava/util/function/Function; //call the map() func invokeinterface java/util/stream/Stream.map: (Ljava/util/function/Function;)Ljava/util/stream/Stream; 

InvokeDynamic是Java 7中添加的一条指令,它使JVM不那么严格,并允许动态语言在运行时绑定符号,而不是在JVM编译代码时静态地执行所有链接。

Lambda代码

 aload_0 invokevirtual java/lang/String.length:() invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer; areturn 

Lambda表达式不会被转换为anonymous inner classes ,它们使用Java 7中引入的调用动态来执行函数方法。 看看这个 。

他们违反了OOP吗? 我不认为你应该关心。 Lambdas使您的代码更简洁,更易于理解,并且“更容易”并行化。 这就是你应该关心的。

来自Brain Goetz评论:

我们没有得到编写面向对象程序或function程序的报酬,我们得到报酬编写工作程序。

  • Lambda表达式使用invokedynamic字节码编译。
  • Lambda实现与特殊的私有方法存储在同一个类文件中。
  • 是否创建对象以调用lambda取决于具体情况。 在简单的情况下,lambda被转换为常量方法句柄。
  • 要实例化lambda HotSpot会创建一个实现lambdafunction接口的匿名类。 此类不属于任何ClassLoader。

查看Lambda Expressions JSR规范负责人的更多详细信息 。