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

12,199

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.

Share:
12,199
masiboo
Author by

masiboo

A motivated Full-Stack software engineer with 16+ years of experience in several industries. Developing experiences in cross-platform such as Windows, Linux, Android, and Cloud Platforms. Recent days focus on Java and AWS.

Updated on June 04, 2022

Comments

  • masiboo
    masiboo almost 2 years

    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?

  • Naman
    Naman over 5 years
    If this is the question to be inferred, how about closing this as a duplicate? Since this doesn't still relate then to the commented out code in the question. At least, the suggestion using map and collect could have solved the problem by not making use of the lambda here at all.