Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaLambdas:它在JVM中的工作原理&;是OOP吗?_Java_Oop_Lambda_Jvm_Java 8 - Fatal编程技术网

JavaLambdas:它在JVM中的工作原理&;是OOP吗?

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是需要时执行的代码块

当遇到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