Error:(343, 83) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量

本文通过一个具体的Java代码示例,深入探讨了Lambda表达式中变量作用域的问题,特别是关于局部变量必须是最终变量或实际上的最终变量的要求。文章提供了详细的错误分析和解决方案,帮助读者理解并避免此类常见陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    /**
     * 问题代码(只是为了重现错误,请忽略代码逻辑)
     */ 
    @Test
    public void test23(){
        ArrayList<Book> list = new ArrayList<>();
        list.add(new Book("魔法书","20"));
        list.add(new Book("武术书","30"));
        list.add(new Book("技能书","50"));
        list.add(new Book("魔法书","20"));
        List<Book> list2 = list;
        String orgShortName;
        List<Book> collect = null;
        for (Book vo : list) {
            if (null != vo){
                orgShortName = "";
                if (!StringUtils.isEmpty(orgShortName)){
                    // Error:(343, 83) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
                    // 即lambda表达式中使用的本地变量 必须是被final变量或是实际只被赋值过一次的变量
                     collect = list2.stream().filter(temp -> temp.getName().equals(orgShortName)).collect(Collectors.toList());
                }
            }
        }
        System.out.println(collect);
    }

问题代码↑:

解决思路↓:

    /**
     * ERROR:"从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量"
     *      即编译器要求:lambda表达式中使用的局部变量(如此处的orgShortName) 必须是被final变量或是实际只被赋值过一次的变量
     * 问题分析:
     *      通常为了节省开销,习惯将遍历中用到的变量声明到外边,这时编译器会认为该变量有被重复赋值的风险,故抛出异常。
     * 解决方法:
     *      考虑将变量声明到遍历内,骗过编译器的判断(使用该方法会使得每次遍历都声明同名变量,稍微加大了资源开销)
     */
    @Test
    public void test23(){
        ArrayList<Book> list = new ArrayList<>();
        list.add(new Book("魔法书","20"));
        list.add(new Book("武术书","30"));
        list.add(new Book("技能书","50"));
        list.add(new Book("魔法书","20"));
        List<Book> list2 = list;
        //String orgShortName;
        List<Book> collect = null;
        for (Book vo : list) {
            if (null != vo){
                String orgShortName = vo.getName();
                if (!StringUtils.isEmpty(orgShortName)){
                    // Error:(343, 83) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
                    // 即lambda表达式中使用的本地变量 必须是被final变量或是实际只被赋值过一次的变量
                    collect = list2.stream().filter(temp -> temp.getName().equals(orgShortName)).collect(Collectors.toList());
                }
            }
        }
        System.out.println(collect);
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值