深入JDK源码探索Java语言Lambda具体实现

本文深入探讨Java Lambda的实现原理,通过JDK源码解析,展示Lambda如何在JVM层面转化为字节码指令,涉及invokedynamic、BootstrapMethod等关键概念。文章还通过实例说明Lambda表达式与匿名内部类的内存泄漏差异,并阐述invokedynamic指令对JVM平台语言发展的深远影响。
摘要由CSDN通过智能技术生成

当我刚刚开始学习Java的Lambda的时候,我曾经完全误解了它的实现方式,并且前段时间发现居然有些朋友和当时的我一样。

比如下面这个例子:

class Foobar {
   
    Runnable foobar() {
   
        return () -> {
   };
    }
}

在最初的时候,我猜想它也许会像这样实现:

class Foobar {
   
    Runnable foobar() {
   
        return new Runnable() {
   
            @Override
            public void run() {
   
                return;
            }
        };
    }
}

实际上,并不是。

当然了,如果真是这样做了也算是一种实现方式,但是Java这里做出了更加巧妙的设计。

这个函数在Java8中经过编译后的字节码是这样的:

  java.lang.Runnable foobar();
    descriptor: ()Ljava/lang/Runnable;
    flags:
    Code:
      stack=1, locals=1, args_size=1
         0: invokedynamic #2,  0              // InvokeDynamic #0:run:()Ljava/lang/Runnable;
         5: areturn
      LineNumberTable:
        line 3: 0

乍一看似乎莫名其妙,run方法其实也实现在了这个类里:

  private static void lambda$foobar$0();
    descriptor: ()V
    flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=0, locals=0, args_size=0
         0: return
      LineNumberTable:
        line 3: 0

它们通过InvokeDynamic这个字节码指令以及一个BootstrapMethod才在两者之间建立起联系:

  0: #16 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #17 ()V
      #18 invokestatic Foobar.lambda$foobar$0:()V
      #17 ()V

看到这里的朋友,大概应该都是用过MethodHandle的吧,不然的话上面这段可能不太好理解。

用Java代码大致模拟一下,运行时的逻辑大概像是这样:

class Foobar {
   
    @SuppressWarnings("unchecked")
    Runnable foobar() throws Throwable {
   
        return (Runnable) LambdaMetafactory.metafactory(
            MethodHandles.lookup(),
            "run",
            MethodType.methodType(Runnable.class),
            MethodType.methodType(void.class),
            MethodHandles.lookup().findStatic(Foobar.class, "lambda$foobar$0", MethodType.methodType(void.class)),
            MethodType.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值