Kotlin 和 Java 中的 Lambda 表达式的区别

本文探讨了Kotlin和Java中Lambda表达式的差异。Kotlin的Lambda表达式在编译后会生成匿名类,但静态和非静态上下文的处理方式不同。Java的Lambda则依赖LambdaMetafactory动态生成匿名类,且要求引用的变量为final或等效final。Kotlin允许非final变量,通过编译时优化处理。
摘要由CSDN通过智能技术生成

Kotlin 的 Lambda 表达式的编译后

源码

我们演示一个简单的 Demo,Lambda 表达式实现 Predicate<Integer>,判断整数是否是偶数的:

class LambdaTest {
   
    
    companion object {
    // 相当于 static 成员
        private fun Int.toBoolean(predicate: (Int) -> Boolean) = predicate(this)
        
        private fun testStaticLambda() {
   
            val x = 1;
            val y = 2;
            val b = 1.toBoolean {
   
                println("$x and $y") // 引用局部变量 x 和 y
                it % 2 == 0
            }
            println(b)
        }
    }
    
    private var x = 1;

    private fun testNonStaticLambda() {
   
        val y = 2;
        val b = 1.toBoolean {
   
            println("$x and $y") // 引用实例变量 x 和局部变量 y
            it % 2 == 0
        }
        println(b)
    }
}

编译后

=> 解读 class 文件得到:

// LambdaTest.class
public final class LambdaTest {
   
	// companion object 被编译成静态 final 变量,并生成匿名类
	public static final LambdaTest$Companion Companion = new LambdaTest$Companion(null);
	
    private int x;
    
    private final void testNonStaticLambda() {
   
        int y = 2;
		boolean b = LambdaTest$Companion.access$toBoolean(
			new LambdaTest$Companion(), 
			1, // lambda 表达式编译成 Fuction1 接口的匿名类,注意这里传入了 this!!!
			(Function1) new LambdaTest$testNonStaticLambda$b$1(this, y));
		System.out.println(b);
	}
    
    /* x 的 setter 和 getter */
	public LambdaTest() {
    this.x = 1; }
    public static final int access$getX$p(LambdaTest $this) {
   /**/}
    public static final void access$setX$p(LambdaTest $this, int n) {
    /**/}
}

伴随对象生成的匿名类 LambdaTest$Companion.class,生成 static 方法。

// LambdaTest$Companion.class
public final class LambdaTest$Companion {
   	
	private final boolean toBoolean(int $this$intToBoolean, Function1<? super Integer, Boolean> predicate) {
   
	    return predicate.invoke($this$intToBoolean); // AutoBox
	}
	
    private final void testStaticLambda() {
   
        int x = 1;
        int y = 2;
        // lambda 表达式编译为 Function1 接口的匿名类
        boolean b = toBoolean(1, (Function1) new LambdaTest$Companion$testStaticLambda$b$1(x, y));
	    System.out.println(b);
	}

	public static final boolean access$toBoolean(LambdaTest$Companion $this, int $this$access_u24toBoolean, Function1 predicate) {
   
        return $this.toBoolean($this$access_u24toBoolean, (Function1<? super Integer, Boolean>)predicate);
    }
    
    private LambdaTest$Companion() {
   }
    public LambdaTest$
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值