Java8的lambda(2)

在开始之前,我先普及一下什么是Single Abstract Method interfaces (SAM Interfaces).简单的说就是只用一个函数的interface。

例如Runnable,Comparable等;

例如下面一个:

package functional;

@FunctionalInterface
public interface SimpleFuncInterface {
  public void doWork();
  
  public String toString();
}


lambda就是通过MethodHandle来实现的。

那么在运行的过程中,它是什么样子的呢?

看看下面的例子:

package functional;

public class SimpleFunInterfaceTest2 {
	public static void main(String[] args) {
		// lambda
		carryOutWork(() -> sleep());
		carryOutWork(() -> sleep());
	}

	private static Object sleep() {
		try {
			Thread.sleep(1500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		 return null;
	}

	public static void carryOutWork(SimpleFuncInterface sfi) {
		sfi.doWork();
	}
}

在Thread.sleep那一行打个断点,这时的堆栈是:

"main" #1 prio=5 os_prio=0 tid=0x00e9cc00 nid=0x5e8 at breakpoint[0x001cf000]
   java.lang.Thread.State: RUNNABLE
    at functional.SimpleFunInterfaceTest.sleep(SimpleFunInterfaceTest.java:24)
    at functional.SimpleFunInterfaceTest.lambda$0(SimpleFunInterfaceTest.java:20)
    at functional.SimpleFunInterfaceTest$$Lambda$1/7599890.doWork(Unknown Source)
    at functional.SimpleFunInterfaceTest.carryOutWork(SimpleFunInterfaceTest.java:34)
    at functional.SimpleFunInterfaceTest.main(SimpleFunInterfaceTest.java:20)

JVM会生成一个7599890实例来实行对应的lambda,如果你再起一个同样的程序,这时的堆栈和第一次是一样的;

如果在第二次嗲用carryOutWork的Thread.sleep上停住的话,这是的堆栈就不一样了,如下图:

这是为什么呢?这是因为两次调用carryOutWork方法,都会在class文件中生成两个lambda方法,所以这里的实例对象不一样;

一个是25332239,一个是7599890.这里的数字应该是根据什么lambda的位置和实现的interface名字生成的,同一个lambda在不同的JVM实例中生成的数字是一样的,

这里应该就是CallSite了。

但是你如果想只生成一个lambda的话,应该怎么办呢?

		SimpleFuncInterface sfi = () -> sleep();
		carryOutWork(sfi);
		carryOutWork(sfi);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值