【Java异常】Variable used in lambda expression should be final or effectively final

2024-10-09 11:21:30 浏览数 (2)

【Java异常】Variable used in lambda expression should be final or effectively final

从字面上来理解这句话,意思是:*lambda表达式中使用的变量应该是final或者有效的final*,也就是说,lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。 要求外部变量为final是在编译期以强制手段确保用户不会在lambda表达式中做修改原变量值的操作。

其实在Java8之前,匿名类中如果要访问局部变量的话,那个局部变量必须显式的声明为final。

Demo代码示例:

代码语言:javascript复制
package com.example.core.mydemo.java8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Java8FinalTest {
    public static void main(String[] args) {
        //如果直接定义变量,不会报错”Variable used in lambda expression should be final or effectively final“
//        List<Integer> number = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        //如果分开赋值,就会报错”Variable used in lambda expression should be final or effectively final“
        List<Integer> number = null;
        number = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        //创建临时中间变量,可以用final也可以不用final
        final List<Integer> numberTmp = number;
        //Variable used in lambda expression should be final or effectively final
        List<Integer> group = Arrays.asList(1,2);
        List<Object> groupResult = group.stream().map(x -> calc(numberTmp)).collect(Collectors.toList());
        groupResult.stream().forEach(System.out :: println);

        //匿名内部类 1.8不会报错
        //1.7会报错:Variable 'jdkVersion' is accessed from within inner class, needs to be declared final,意思是:变量‘dkVersion’在匿名内部类中被访问,必须被声明为final类型的。
        String jdkVersion = "1.7";
        testFinal(new Suppliers(){
            @Override
            public String get() {
                return jdkVersion;
            }
        });
    }

    public static void testFinal(Suppliers supplier){
        System.out.println("supplier="   supplier.get());
    }


    private static Object calc(List<Integer> number) {
        //变量不允许修改
//        number.add(11);  Exception in thread "main" java.lang.UnsupportedOperationException
        return number.stream().mapToInt(x -> x).sum();
    }

    static class Suppliers{
        public String get(){
            return "hello world";
        }
    }
}

0 人点赞