JavaLambdas:它在JVM中的工作原理&;是OOP吗?
例如,对于匿名内部类,传递(匿名)对象引用并执行该对象的方法 lambda是需要时执行的代码块 当遇到lambda时,JVM中会发生什么?JVM在哪里存储与lambdas相关的代码块(堆:年轻的、老的或永久的生成) 我尝试了搜索,得到了使用lambdas的语法,但无法理解JVM内部发生了什么,因为在JAVA中,一切都是基于对象的JavaLambdas:它在JVM中的工作原理&;是OOP吗?,java,oop,lambda,jvm,java-8,Java,Oop,Lambda,Jvm,Java 8,例如,对于匿名内部类,传递(匿名)对象引用并执行该对象的方法 lambda是需要时执行的代码块 当遇到lambda时,JVM中会发生什么?JVM在哪里存储与lambdas相关的代码块(堆:年轻的、老的或永久的生成) 我尝试了搜索,得到了使用lambdas的语法,但无法理解JVM内部发生了什么,因为在JAVA中,一切都是基于对象的 那么在面向对象的环境中,lambdas是如何工作的呢 lambda是否违反OOP概念 Lambda是否适合垃圾收集器,因为没有创建任何对象 不用担心内存问题和清除内存
Lambda表达式不会被翻译成
匿名内部类
,它们使用Java 7中引入的匿名内部类来执行函数方法
他们是否违反了OOP?我认为你不应该在意。lambda使您的代码不那么冗长,更容易理解,并且“更容易”并行化。这就是你应该关心的
来自Brain Goetz评论:
我们不是为了编写面向对象的程序或函数式程序而获得报酬,而是为了编写工作程序而获得报酬
- Lambda表达式是使用
字节码编译的invokedynamic
- Lambda实现作为一个特殊的私有方法存储在同一个类文件中
- 是否创建对象来调用lambda取决于具体情况。在一般情况下,lambda被转换为常量方法句柄
- 要实例化lambda热点,将创建一个实现lambda函数接口的匿名类。此类不属于任何类加载器
请参阅。的规范导言,我不会浪费时间思考lambda表达式是否违反了OO原则。它的目标是提高语言的能力,而不是编写OO代码,我不认为lambdas会违反封装、继承或多态性 这解释了Java如何处理lambda表达式: Lambda表达式的有趣之处在于,从JVM的角度来看,它们是完全不可见的。它不知道什么是匿名函数或Lambda表达式。它只知道字节码,这是一个严格的OO规范。这取决于语言及其编译器的制造商如何在这些约束条件下创建更新、更高级的语言元素 考虑到以下准则:
List names = Arrays.asList("1", "2", "3");
Stream lengths = names.stream().map(name -> name.length());
。。。它一开始非常简单,加载names var并调用其.stream()
方法,但随后它做了一些非常优雅的事情。它使用Java 7中添加的新invokeDynamic
指令动态链接此调用站点与实际Lambda函数,而不是创建一个包装Lambda函数的新对象
InvokeDynamic
是在Java 7中添加的一条指令,用于降低JVM的严格性,并允许动态语言在运行时绑定符号,而不是在JVM编译代码时静态执行所有链接
Lambda码
aload_0
invokevirtual java/lang/String.length:()
invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
areturn
我认为lambdas是另一种编写代码更紧凑(或者更好)的方法。OOP的范式不是这样被触动的,但这是我的观点。lambdas是函数编程的重要部分,正如OOP中所知道的那样。在表面上,lambda符号似乎违反了“结构化编程”的一些规则,这是OOP(很少提及)的基础。不过,我对它的研究还不够深入,在过去的10年里,javac已经变成了一个庞大的非结构化混乱体。如果我们担心lambda是如何在编译器或虚拟机中实现的,难道有人不应该先对所有这些GOTO做些什么吗?一个常见的误解是OOP和FP在某种程度上是不一致的。但我们并不是为了编写面向对象的程序或函数式程序而获得报酬,而是为了编写工作程序而获得报酬(无论如何,在理想情况下)。OOP和FP都为我们提供了控制编程自然复杂性的工具;作为程序员,我们应该尽可能多地从OOP和FP中学习,并在有助于实现编写工作的、可维护的、可测试的、可读的、无错误的程序的目标的地方使用它们所教的内容。在某些情况下,Afaik Lambda确实会被翻译成匿名内部类。但是,调用的动态引导处理程序会在运行时产生这种情况,该处理程序会找出处理特定lambda的最佳策略。@8472从某种程度上说,这条语句在针对头天使的意义上可能是正确的,但它仍然是一个负面的有用特性。您最好还是放弃与内部类的任何连接——这将有助于更好地理解。@BrianGoetz,它实际上不应该是lambdas的特征,更应该是对实现细节的吹毛求疵。@the8472:它是一个可能生成的类,它实际上被称为“内部类”然而,即使在工厂里,它也缺少普通内部类与顶级类不同的各个方面,“内部”和“外部”类都不包含任何关于内部类关系的信息。啊,我明白了。我想我被lambda工厂中的内部类内容+调用堆栈中出现的合成方法弄糊涂了。谢谢,这不是答案。它是“嘿,它使用invokedynamic,go和googleit”。这实际上是一个答案,这就是OP接受它的原因。
aload_0
invokevirtual java/lang/String.length:()
invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
areturn