Kotlin|探秘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{ 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() }

【Kotlin|探秘Kotlin Lambda表达式在 jvm 上的实现】这段代码通过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 ) { Intrinsics.checkParameterIsNotNull(, ""); funType = ; }public final Function1 getFuncT() { return funcT; }public final void setFuncT(Function1 ) { Intrinsics.checkParameterIsNotNull(, ""); funcT = ; }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 关键字,解决编译生成匿名类的问题,还省去了 把操作包装成匿名类对象的开销

    推荐阅读