Lambda 表达式一些理解

由于工作原因,公司使用JDK7的版本, JDK8几乎没有使用到。

之前曾经了解到Lambda 表达式, function功能性函数,ConcurrentHashMap等在JDK8了升级优化等。

中文版 jdk8官方说明:https://www.oracle.com/cn/java/technologies/javase/8-whats-new.html

仅仅对相关重要的特性做一下学习。

1. Lambda 表达式, 相信凡是使用过JDK8的人,应该对这个耳熟能详了。

   但Lambda 的实现原理呢?

  先来一个demo  , 其中 (o1, o2) -> o1.compareTo(o2), 就是一个Lambda表达式。


public class LambdaTest {

	private volatile int age = 1;

	public static void main(String[] args) {

		List<Integer> list = new ArrayList<>();
		list.add(1);
		list.add(10);
		list.add(3);
		list.add(2);
		list.add(18);

		Collections.sort(list, (o1, o2) -> o1.compareTo(o2));
	}
}

我们来看一下, 这个测试类,生成的字节码是什么。通过

javap -c -p LambdaTest.class 得到下面信息。
 * <pre>
 *   Compiled from "LambdaTest.java"
 * public class com.hjb.learning.jdk8.LambdaTest {
 *   public com.hjb.learning.jdk8.LambdaTest();
 *     Code:
 *        0: aload_0       
 *        1: invokespecial #1                  // Method java/lang/Object."<init>":()V
 *        4: return        
 *
 *   public static void main(java.lang.String[]);
 *     Code:
 *        0: new           #2                  // class java/util/ArrayList
 *        3: dup           
 *        4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
 *        7: astore_1      
 *        8: aload_1       
 *        9: iconst_1      
 *       10: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
 *       13: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
 *       18: pop           
 *       19: aload_1       
 *       20: bipush        10
 *       22: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
 *       25: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
 *       30: pop           
 *       31: aload_1       
 *       32: iconst_3      
 *       33: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
 *       36: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
 *       41: pop           
 *       42: aload_1       
 *       43: iconst_2      
 *       44: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
 *       47: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
 *       52: pop           
 *       53: aload_1       
 *       54: bipush        18
 *       56: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
 *       59: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
 *       64: pop           
 *       65: aload_1       
 *       66: invokedynamic #6,  0      //这一行注意了       // InvokeDynamic #0:compare:()Ljava/util/Comparator;
 *       71: invokestatic  #7                   // Method java/util/Collections.sort:(Ljava/util/List;Ljava/util/Comparator;)V
 *       74: return        
 *
 *   private static int lambda$main$0(java.lang.Integer, java.lang.Integer);
 *     Code:
 *        0: aload_0       
 *        1: aload_1       
 *        2: invokevirtual #8                  // Method java/lang/Integer.compareTo:(Ljava/lang/Integer;)I
 *        5: ireturn       
 * }
 * 
 * 
 * </pre>

可以发现,在反编译之后出现了invokedynamic指令,以及一个lambda$main$0静态方法, 静态方法是比较2个Integer信息。

 所以可以大胆的猜测lambda表达式,底层是通过invokedynamic实现的。

其实可以通过在运行是加上-Djdk.internal.lambda.dumpProxyClasses=path,生成lambda内部类的方式,看看究竟。

* <pre>
 * 使用jad反编译工具之后, lambda实际生成的是一个final的内部类。
 * final class LambdaTest$$Lambda$1 implements Comparator {
 * 
 * 	public int compare(Object obj, Object obj1) {
 * 		return LambdaTest.lambda$main$0((Integer) obj, (Integer) obj1);
 * 	}
 * 
 * 	private LambdaTest$$Lambda$1() {
 * 	}
 * }
 * 
 * </pre>

 

这样看着貌似很明显了,  (o1, o2) -> o1.compareTo(o2)生成了一个实现Comparator的类, 类的主题逻辑就是调用之前产生的

lambda$main$0的静态方法。

这样就形成了一个思路: lambda生成了一个类,同时也生成了一个静态方法。 然后应用程序在调用lambda对应代码的时候,其实就是调用的这个类,然后调用到静态方法。

以上这些都是JDK给我们自动生成了。当然这个仅仅是站在巨人的肩膀上,开发人员可以这样简单的理解。

 

lambda最核心的思想是invokedynamic指令的应用。 如果想要了解怎么生成这些信息的,建议先了解invokedynamic。

然后再看一下LambdaMetafactory类,膜拜下牛人的设计思想和代码理念

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值