闭包
关键就是上连接中这个void lambda$create$0(int)中的int参数
int factor = 3;
numbers.stream()
.filter(e -> e % 2 == 0)
.map(e -> e * factor)
.collect(toList());
map 方法现在接受一个闭包,而不是一个 lambda 表达式。我们知道,这个闭包接受一个参数 e,但它也捕获并携带 factor
变量的状态。
private static void lambda$create$0(int);
Code:
0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
3: iload_0
4: invokevirtual #9 // Method java/io/PrintStream.println:(I)V
7: return
}
所以lambda表达式才能这么写,但是i的值在lambda表达式中值不能变,想变的话,可以使用类实例变量或者静态变量,或者AtomInteger原子类。
看一个例子:
protected boolean saveDataToSql(String topic, MqttMessage mqttMessage) {
int i=0;
saveMachineEjectionDataToSqlThread.execute(() -> {
System.out.println(i);// 闭包
});
return true;
}
java反编译后lambda多了一个int变量
private static void lambda$saveDataToSql$0(int);
descriptor: (I)V
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream;
3: iload_0
4: invokevirtual #14 // Method java/io/PrintStream.println:(I)V
7: return
LineNumberTable:
line 38: 0
line 57: 7
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 i I
MethodParameters:
Name Flags
i final synthetic
查看saveDataToSql反编译:
7: invokedynamic #11, 0 // InvokeDynamic #0:run:(I)Ljava/lang/Runnable;执行这句这个方法传入int返回Runnable
12: invokevirtual #12 // Method cm/soft/collect/threadUtil/CustomThread.execute:(Ljava/lang/Runnable;)V
执行excecute方法,传入Runnable返回void
protected boolean saveDataToSql(java.lang.String, org.eclipse.paho.client.mqttv3.MqttMessage);
descriptor: (Ljava/lang/String;Lorg/eclipse/paho/client/mqttv3/MqttMessage;)Z
flags: ACC_PROTECTED
Code:
stack=2, locals=4, args_size=3
0: iconst_0
1: istore_3
2: aload_0
3: getfield #8 // Field saveMachineEjectionDataToSqlThread:Lcm/soft/collect/threadUtil/CustomThread;
6: iload_3
7: invokedynamic #11, 0 // InvokeDynamic #0:run:(I)Ljava/lang/Runnable;
12: invokevirtual #12 // Method cm/soft/collect/threadUtil/CustomThread.execute:(Ljava/lang/Runnable;)V
15: iconst_1
16: ireturn
LineNumberTable:
line 35: 0
line 37: 2
line 59: 15
LocalVariableTable:
Start Length Slot Name Signature
0 17 0 this Lcm/soft/collect/biz/MachineEjectionBizState;
0 17 1 topic Ljava/lang/String;
0 17 2 mqttMessage Lorg/eclipse/paho/client/mqttv3/MqttMessage;
2 15 3 i I
MethodParameters:
Name Flags
topic
mqttMessage
有一个内部类:通过句柄找到lambda表达式的引用 #68 = MethodHandle #6:#87 // invokestatic cm/soft/collect/biz/MachineEjectionBizState.lambda$saveDataToSql$0:(I)V
RuntimeVisibleAnnotations:
0: #52()
InnerClasses:
public static final #103= #102 of #106; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
0: #66 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#67 ()V
#68 invokestatic cm/soft/collect/biz/MachineEjectionBizState.lambda$saveDataToSql$0:(I)V
#67 ()V