java拉姆达表达式原理_Java 8 Lambda表达式实现原理解析

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:50   2380   0

Lambda原理

在Java8中每一个表达式必须有一个函数式接口与之对应。

什么函数式接口?

简单的说就是只包含一个抽象方法的普通接口

Lambda表达式的使用。

我们定义了一个IMath接口,加上@FunctionalInterface注解

public class LambdaTest {

@FunctionalInterface

interface IMath{

int operation(int a, int b);

}

int testLambda(IMath lambdaTest, int a , int b) {

return lambdaTest.operation(a,b);

}

public static void main(String[] args) {

LambdaTest lambdaTest = new LambdaTest();

int result = lambdaTest.testLambda(

(a,b) -> a + b

, 1, 2);

System.out.println(result);

}

}

然后定义一个testLambda方法,最终在main方法中使用lambda表达式。

1、使用字节码查看工具 javap -p LambdaTest.class

-p表示输出所有的类及成员

Compiled from "LambdaTest.java"

public class java8.LambdaTest {

public java8.LambdaTest();

int testLambda(java8.LambdaTest$IMath, int, int);

public static void main(java.lang.String[]);

private static int lambda$main$0(int, int);

}

可以看到生成了一个源码没有的私有的静态函数private static int lambda$main$0(int, int);

如何实现这个私有静态方法呢?我们在LambdaMetafactory类中的metafactory方法上打上断点

最终进入metafactory这个方法

public static CallSite metafactory(MethodHandles.Lookup caller,

String invokedName,

MethodType invokedType,

MethodType samMethodType,

MethodHandle implMethod,

MethodType instantiatedMethodType)

throws LambdaConversionException {

AbstractValidatingLambdaMetafactory mf;

mf = new InnerClassLambdaMetafactory(caller, invokedType,

invokedName, samMethodType,

implMethod, instantiatedMethodType,

false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);

mf.validateMetafactoryArgs();

return mf.buildCallSite();

}

这个函数的作用: 为Lambda表达式生成一个内部类。这个类是怎么样的?

2、查看metafactory函数生成的内部类

在Idea 的VM options配置-Djdk.internal.lambda.dumpProxyClasses

运行后,会将生成的内部类class输出到一个文件中

package java8;

import java.lang.invoke.LambdaForm.Hidden;

import java8.LambdaTest.IMath;

// $FF: synthetic class

final class LambdaTest$$Lambda$1 implements IMath {

private LambdaTest$$Lambda$1() {

}

@Hidden

public int operation(int var1, int var2) {

return LambdaTest.lambda$main$0(var1, var2);

}

}

最终调用的是LambdaTest的内部私有静态方法 lambda$main$0(var1, var2);

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP