探秘Kotlin Lambda表达式在 jvm 上的实现

Kotlin lambada 表达式的类型

Kotlin lambada 表达式的类型 ,是函数类型。

class FunctionTest {
    /***
     *  通过 fun  +  =  + {}  定义一个 返回值为  函数类型 的 函数
     */
    fun foo()  = { x:Int->
        println("  这是一个 返回值为函数类型的  函数")
        var num =x.plus(x)
        num
    }

    /***
     * 定义一个 函数类型的变量
     * 为什么 kotlin 会比java 多一个函数类型   类型出来?
     * 编译后 ,funType 是一个 类似 java 的函数接口对象
     */
    var funType = {
        num:Int ->
        println("  这是一个 成员变量Lambada 表达式")
        num.plus(num)
    }

    /***
     * 直接定义一个匿名的 接口 对象
     */
    var funcT  = object : Function1<Int,Int>{
        override fun invoke(p1: Int): Int {
            var num =p1.plus(p1)
            println("  这是一个 匿名内部类对象")
            return num
        }

    }

    /***
     * 定义一个 高阶函数
     */
    fun test(intNum: Int, func:(Int) ->Int){
        println(" 测试 " +func(intNum))
    }

    fun doTest(){
        test(100){
            println(" 测试 这是一个匿名的 Lambada 表达式" )
            it.plus(it)
        }
        test(101,funType)
        test(102,foo())
        test(103,funcT)

    }
}

fun main() {
    var cl= FunctionTest()
    cl.doTest()
}

这段代码通过jad 反编译后

import kotlin.jvm.functions.Function1;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.Lambda;

public final class FunctionTest
{

    public final Function1 foo()
    {
        static final class foo._cls1 extends Lambda
            implements Function1
        {

            public volatile Object invoke(Object obj)
            {
                return Integer.valueOf(invoke(((Number)obj).intValue()));
            }

            public final int invoke(int x)
            {
                String s = "  \u8FD9\u662F\u4E00\u4E2A \u8FD4\u56DE\u503C\u4E3A\u51FD\u6570\u7C7B\u578B\u7684  \u51FD\u6570";
                boolean flag = false;
                System.out.println(s);
                int num = x + x;
                return num;
            }

            public static final foo._cls1 INSTANCE = new foo._cls1();


        }

        return (Function1)foo._cls1.INSTANCE;
    }

    public final Function1 getFunType()
    {
        return funType;
    }

    public final void setFunType(Function1 <set-?>)
    {
        Intrinsics.checkParameterIsNotNull(<set-?>, "<set-?>");
        funType = <set-?>;
    }

    public final Function1 getFuncT()
    {
        return funcT;
    }

    public final void setFuncT(Function1 <set-?>)
    {
        Intrinsics.checkParameterIsNotNull(<set-?>, "<set-?>");
        funcT = <set-?>;
    }

    public final void test(int intNum, Function1 func)
    {
        Intrinsics.checkParameterIsNotNull(func, "func");
        String s = (new StringBuilder()).append(" \u6D4B\u8BD5 ").append(((Number)func.invoke(Integer.valueOf(intNum))).intValue()).toString();
        boolean flag = false;
        System.out.println(s);
    }

    public final void doTest()
    {
        static final class doTest._cls1 extends Lambda
            implements Function1
        {

            public volatile Object invoke(Object obj)
            {
                return Integer.valueOf(invoke(((Number)obj).intValue()));
            }

            public final int invoke(int it)
            {
                String s = " \u6D4B\u8BD5 \u8FD9\u662F\u4E00\u4E2A\u533F\u540D\u7684 Lambada \u8868\u8FBE\u5F0F";
                boolean flag = false;
                System.out.println(s);
                return it + it;
            }

            public static final doTest._cls1 INSTANCE = new doTest._cls1();


        }

        test(100, (Function1)doTest._cls1.INSTANCE);
        test(101, funType);
        test(102, foo());
        test(103, funcT);
    }

    public FunctionTest()
    {
        static final class funType._cls1 extends Lambda
            implements Function1
        {

            public volatile Object invoke(Object obj)
            {
                return Integer.valueOf(invoke(((Number)obj).intValue()));
            }

            public final int invoke(int num)
            {
                String s = "  \u8FD9\u662F\u4E00\u4E2A \u6210\u5458\u53D8\u91CFLambada \u8868\u8FBE\u5F0F";
                boolean flag = false;
                System.out.println(s);
                return num + num;
            }

            public static final funType._cls1 INSTANCE = new funType._cls1();


        }

        funType = (Function1)funType._cls1.INSTANCE;
        funcT = (Function1)new Function1() {

            public Integer invoke(int p1)
            {
                int num = p1 + p1;
                String s = "  \u8FD9\u662F\u4E00\u4E2A \u533F\u540D\u5185\u90E8\u7C7B\u5BF9\u8C61";
                boolean flag = false;
                System.out.println(s);
                return Integer.valueOf(num);
            }

            public volatile Object invoke(Object obj)
            {
                return invoke(((Number)obj).intValue());
            }

        }
;
    }

    private Function1 funType;
    private Function1 funcT;
}

一目了然,Kotlin 的函数类型在JVM 平台是以匿名内部类实现的 ,和java的实现方式一样,不过Kotlin 的编译器更为强大,在编辑时我们 可以用函数类型 来定义Lambada表达式

Kotlin 和java Lambda 表达式在jvm上的区别

  • java 在SE7 后 通过 invokedynamic 技术 优化了:Lambda 表达式 在编译时会产生大量匿名类字节码的问题(功能的字节码是子运行时生成的),运行时生成:减少了编译文件的大小。 还给后续优化留有了余地。
  • Kotlin 引入了内联机制,也就是 inline 关键字,解决编译生成匿名类的问题,还省去了 把操作包装成匿名类对象的开销
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值