Java 8使用lambda表达式捕获22并且实际上是final [英] Java 8 catch 22 with lambda expressions and effectively final

查看:351
本文介绍了Java 8使用lambda表达式捕获22并且实际上是final的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩Java 8并且遇到一个基本场景,它说明了修复一个编译错误导致另一个编译错误的问题22。场景(这只是一个从更复杂的东西中简化的示例):

I'm playing with Java 8 and hit a basic scenario that illustrates a catch 22 where fixing one compile error causes another compile error. The scenario (which is just an example simplified from something more complex):

public static List<String> catch22(List<String> input) {
    List<String> result = null;
    if (input != null) {
      result = new ArrayList<>(input.size());
      input.forEach(e -> result.add(e)); // compile error here
    }

    return result;
}

我收到编译错误:


在封闭范围内定义的局部变量结果必须是最终的或有效的最终

Local variable result defined in an enclosing scope must be final or effectively final

如果我将第一行更改为:

If I change the first line to:

List<String> result;

我在最后一行收到编译错误:

I get a compile error on the last line:


本地变量结果可能尚未初始化

The local variable result may not have been initialized

这似乎是唯一的方法是将我的结果预初始化为ArrayList,我不想这样做,或者不使用lambda表达式。我错过了任何其他解决方案吗?

It seems like the only approach here is to pre-initialize my result to an ArrayList, which I don't want to do, or not use lambda expressions. Am I missing any other solution?

推荐答案

错误即将发生,因为您的结果 list不是 final ,这是它在lambda中使用的要求。一种选择是在 if 条件内声明变量,并在外部返回null; 。但我认为这不是一个好主意。您当前的方法没有做任何有效的工作。从它返回一个空列表会更有意义。

The error is coming because your result list is not effectively final which is a requirement for it's usage in lambda. One option is to declare the variable inside the if condition, and return null; outside. But I don't think that would be good idea. Your current method is not doing anything productive. It would make much more sense to return an empty list from it.

我已经说过了,因为你正在玩Java 8,所以使用 可选 以及流这里:

Having said that all, I would say, since you are playing with Java 8, use Optional along with streams here:

public static List<String> catch22(List<String> input) {
    return Optional.ofNullable(input)
            .orElse(new ArrayList<String>())
            .stream().collect(Collectors.toList());
}

如果你想返回 null ,我可能会将您的方法更改为:

And if you want to return null, I'll probably change your method to:

public static List<String> catch22(List<String> input) {
    if (input == null) return null;
    return input.stream().collect(Collectors.toList());
    // Or this. B'coz this is really what your code is doing.
    return new ArrayList<>(input);
}

这篇关于Java 8使用lambda表达式捕获22并且实际上是final的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆