lambda 中使用的 Java 8 流变量应该是最终的或有效最终的

mas*_*boo 5 java variables final java-8 java-stream

这个问题已经被问到了。但今天我发现了一些奇怪的事情。对于以下代码:-

public static List<EsbBucketInstanceDefinition> convertBucketDefinitionList(List<BucketInstanceDefinitionV1> bucketInstanceDefinitionV1List) {
    List<EsbBucketInstanceDefinition> response = new ArrayList<>();
    List<EsbBucketInstanceDefinition> finalResponse = new ArrayList<>();
    bucketInstanceDefinitionV1List.stream().forEach(e -> {
        EsbBucketInstanceDefinition esbBucketInstanceDefinition = new EsbBucketInstanceDefinition();
        esbBucketInstanceDefinition.setInstanceType(e.getInstanceType());
        esbBucketInstanceDefinition.setReportingGroup(e.getReportingGroup());
        esbBucketInstanceDefinition.setSliceVolume(e.getSliceVolume());
        esbBucketInstanceDefinition.setCounterName(e.getCounterName());
        esbBucketInstanceDefinition.setSubscriberGroupId(e.getSubscriberGroupId());
        // response.add(esbBucketInstanceDefinition); compiler error variable used in lambda should be final or effective final 
        finalResponse.add(esbBucketInstanceDefinition);
    });
    return finalResponse;
}
Run Code Online (Sandbox Code Playgroud)

因为这个效果很好。看起来只有变量名 FinalResponse 有效。如何以及为何?这样做有效吗?

Boh*_*ian 4

只能在 lambda 中(有效地)引用最终变量。

该引用finalResponse实际上是最终的,因为它永远不会改变。请注意,更改引用意味着为其分配新值,例如

finalResponse = someOtherList;
Run Code Online (Sandbox Code Playgroud)

更改所引用的对象的状态(例如,将项目添加到所引用的列表中finalResponse)与变量所持有的值无关finalResponse,即

finalResponse.add(something);
Run Code Online (Sandbox Code Playgroud)

不改变变量finalResponse;它仅更改引用的对象finalResponse