Java 8 stream variable used in lambda should be final or effectively final

masiboo :

This question is already asked. But today I found something odd. For the following code:-

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;
}

For this works fine. Looks like only variable name finalResponse is working. How and why? Is it valid to do?

Bohemian :

References may only be made to (effectively) final variables from within a lambda.

The reference held by finalResponse in effectively final, because it never changes. Note that changing the reference means assigning a new value to it, eg

finalResponse = someOtherList;

Changing the state of the object referred to (eg adding items to the list referred to by finalResponse) is irrelevant to what the value held by the variable finalResponse, ie

finalResponse.add(something);

Does not change the variable finalResponse; it only changes the object to which finalResponse refers.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=153158&siteId=1